React学习(一)描述UI
本文为本人阅读React官方中文文档后所做笔记,之前学过vue,感觉和vue有一些相似之处,也有很多东西对于我自己来说不需要多说,所以写的比较简洁一点。
组件
React的应用程序是由组件构成,一个组件是界面的一部分。可以将一些界面封装成组件,嵌套到其他界面中,这点和vue一样。让这些界面代码具有复用性。
一个组件:
function MyButton() {return (<button>我是一个按钮</button>);
}
组件嵌套:
export default function MyApp() {return (<div><h1>欢迎来到我的应用</h1><MyButton /></div>);
}
一般情况都是组件的标签是大写字母开头的,传统html标签是小写开头的。
导出组件也是使用export,默认导出只能有一个,可以有多个具名导出。
JSX
return后面的html结构称为JSX语法,是一种JavaScript的拓展语法,支持在JavaScript中写一些类似HTML结构的代码。一个组件不能返回多个JSX标签,要返回多个时候,要用<></>空标签或者<div><div/>包裹,做到只返回一个标签。
展示变量
在jsx中要展示变量中的数据,使用{ xxx }的方式,将变量写在xxx的位置,就能做到展示指定变量的数据。
return (<h1>{user.name}</h1>
);
如果要将变量赋值到某个html属性中,使用 属性={变量} 的方式(相当于vue中的 :属性="变量")
return (<imgclassName="avatar"src={user.imageUrl}/>
);
和vue中一样,这个“变量”的位置并不是只能放置变量,也可以放置匿名对象、表达式:
const user = {name: 'Hedy Lamarr',imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',imageSize: 90,
};export default function Profile() {return (<><h1>{user.name}</h1><imgclassName="avatar"src={user.imageUrl}alt={'Photo of ' + user.name}style={{width: user.imageSize,height: user.imageSize}}/></>);
}
渲染
条件渲染
条件渲染没有类似于vue中的v-if之类的语法,而是直接使用js中的分支语句去控制JSX的内容。
let content;
if (isLoggedIn) {content = <AdminPanel />;
} else {content = <LoginForm />;
}
return (<div>{content}</div>
);
也可以使用三目运算符的方式
<div>{isLoggedIn ? (<AdminPanel />) : (<LoginForm />)}
</div>
如果不需要else if或者else分支,也可以使用&&的方式
<div>{isLoggedIn && <AdminPanel />}
</div>
列表渲染
列表渲染通常使用数组的map方式映射,返回一个JSX数组,再return。
const products = [{ title: 'Cabbage', id: 1 },{ title: 'Garlic', id: 2 },{ title: 'Apple', id: 3 },
];
const listItems = products.map(product =><li key={product.id}>{product.title}</li>
);return (<ul>{listItems}</ul>
);
在li标签中,也要和vue中的列表渲染一样,带上一个key,每个列表项传入一个唯一的值,确保dom更新的时候的正确性。
Props通信
和vue中一样,react可以通过props进行数据的父传子,包括变量、函数。
我们常见的很多html属性也是props的一种,比如image标签中的url等等。所以props的写法和html属性的写法类似。
父组件:
export default function MyApp() {const [count, setCount] = useState(0);function handleClick() {setCount(count + 1);}return (<div><h1>共同更新的计数器</h1><MyButton count={count} onClick={handleClick} /><MyButton count={count} onClick={handleClick} /></div>);
}
子组件:
在组件的函数参数上写上指定的参数名,就能接收到指定的props信息。
function MyButton({ count, onClick }) {return (<button onClick={onClick}>点了 {count} 次</button>);
}
也可以采用不解构的方式,直接都放到props对象中,再引用props中指定的属性:
function MyButton(props) {return (<button onClick={props.onClick()}>点了 {props.count} 次</button>);
}
在子组件中,如果要指定某个props属性在没有接收到值的时候,会有一个默认值,则可以采用设置默认值的方式:
function Avatar({ person, size = 100 }) {// ...
}
如果涉及到多代传递,需要把本组件接收到的所有props,传递给下一个子组件,可以使用展开语法:
function Profile(props) {return (<div className="card"><Avatar {...props} /></div>);
}
还可以将JSX作为props传递,类似于vue中的插槽,可以做到动态切换ui的html结构
import Avatar from './Avatar.js';function Card({ children }) {return (<div className="card">{children}</div>);
}export default function Profile() {return (<Card><Avatarsize={100}person={{ name: 'Katsuko Saruhashi',imageId: 'YfeOqp2'}}/></Card>);
}