组件(Component)
Element V.S. Component
元素与组件
const div = React.createElement('div', ...)- 这是一个 React 元素(d小写)
const Div = ()=>React.createElement(''div), ...- 这是一个 React 组件(D大写)
什么是组件
- 一个返回 React 元素的函数就是组件
- 在 Vue 里, 一个构造选项就可以表示一个组件
React 两种组件
- 函数组件
function Welcome(props) {
return <h1>Hello, {props.name}</div>;
}
- 使用方法:
<Welcome name = 'ivan'> - 类组件
class Welcom extends React.Component {
render() {
return <h1> Hello, {this.props.name} <h1>
}
}
- 使用方法:
<Welcome name = "ivan">
标签会被翻译为 React.createElement
会被翻译成什么
- <div />会被翻译成
React.createElement('div') - <Welcome />翻译为
React.createElement(Welcome) - 可以用 babel 尝试一下
React.createElement 的逻辑
- 如果传入一个字符串'div', 则会创建一个 div
- 如果传入一个函数, 则会调用该函数, 获取其返回值
- 如果传入一个类, 则在类前面价格 new (这会导致执行 constructor) , 获取一个组件对象, 然后调用对象的 render 方法, 获取其返回值
类组件和函数组件使用 props
添加 props (外部数据)
- 类组件直接读取属性 this.props.xxx
- 函数组件直接读取参数 props.xxx
添加 state (内部数据)
-
类组件用 this.state 读, this.setState 写
-
this.setState 不会马上去改变 this.state, 最好用函数去区分state的新旧
-
函数组件用 useState 返回数组, 第一项读, 第二项写
-
setN 永远不会改变 this.state.n
类组件注意事项
this.state.n += 1 无效?
- 其实 n 已经改变了, 只不过 UI 不会自动更新
- 调用 setState 才会触发 UI 更新 (异步更新)
- 因为 React 没有像 Vue 监听 data 一样监听 state
setState 会异步更新 UI
- setState 之后, state 不会马上改变, 立马读 state 会失败
- 更推荐的方式是 setState(函数)
this.setState(this.state) 不推荐
- React 希望我们不要修改旧 state(不可变数据)
- 常用代码: setState({n: state.n + 1})
函数组件注意事项
跟类组件类似的地方
- 也要通过 setX(新值) 来更新 UI
跟类组件不同的地方
- 没有 this, 一律用参数和变量
复杂 state
如果 state 里不止有 n 怎么办
- 类组件里有 n 和 m
- 函数组件里有 n 和 m
总结
- 类组件的 setState 会自动合并第一层属性
- 但是并不会合并第二层属性
- 可以使用 Object.assign 或者 ...操作符
- 函数组件的 setX 则完全不会帮你合并(可使用...操作符使其合并)
事件绑定
类组件的事件绑定
- <button onClick={()=> this.add()}>n+1</button>
- 传一个函数给 onClick 即可, 注意 C 大写
- this.addN = ()=> this.setState({ n: this.state.n + 1 });
- addN = ()=> this.setState({ n: this.state.n + 1 });
- 绑定事件的最终写法
- 绑定事件的最终写法