组件分类
函数组件
function Welcome(props) {return <h1>Hello,{props.name}</h1>}// 使用<Welcome name="frank"/>
类组件
class Welcome extends React.Component {render() {return <h1>Hello,{this.props.name}</h1>}}// 使用<Welcome name="Frank" />
<Welcome /> 会变成一个react 语法,而不是变成HTML元素
<div />会被翻译为React.createElement('div')
<Welcome />翻译为React.createElement(Welcome)
props(外部数据)
外部数据不能写 只能读取
类子组件
this.props.xxx
// 父组件function App() {return (<div className="App">爸爸<Son messageForSon="我是你爸爸" /> // “123”字符串或者JS表达式{a+b}</div>)}// 类子组件class Son extends React.Component {render() {return (<div className="Son">{this.props.messageForSon}</div>)}}
函数子组件
props.xxx
// 父组件class Son extends React.Component {render() {return (<div className="Son">{this.props.messageForSon}<Grandson messageForGrandSon="训责你" /></div>)}}// 子组件const Grandson = (props) => {return (<div className="Grandson">{props.messageForGrandSon}</div>)}
state(内部数据)
类组件
// 声明constructor() {super()this.state = {n: 0}}// 调用n: {this.state.n}// 更新<buttononClick={() => {this.add()}}>+14</button>add() {// 写法一// this.setState({ n: this.state.n + 1 }) // 重新声明一个对象// 写法二// 这里的n 不会立刻变 会等一会儿改变this.setState(state => {const n = state.n + 1return { n }})}
setState(函数) 最好用这个方式 方法一里面的n 不会同步更新。
函数组件
// n 是读的值 setN 是写的值const [n, setN] = React.useState(0)// 读取n:{n}// 写setN(n + 1) // 永远不会改变n 会产生一个新的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, 一律用参数和变量
引用多个值
类组件
class Son extends React.Component {constructor() {super();this.state = {n: 0,m: 0};}addN() {this.setState({ n: this.state.n + 1 });// m 会被覆盖为 undefined 吗?}addM() {this.setState({ m: this.state.m + 1 });// n 会被覆盖为 undefined 吗?}render() {return (<div className="Son">儿子 n: {this.state.n}<button onClick={() => this.addN()}>n+1</button>m: {this.state.m}<button onClick={() => this.addM()}>m+1</button><Grandson /></div>);}}
当其中一个值修改时,另一个值会沿用上次的值,而不会被undefined覆盖。
注意类组件的setState只会合并第一层的属性不会合并下一层的属性。案例
如果要合并可以采取 Object.assign()将第上层数据拿过来。案例
const user = Object.assign({}, this.state.user);
如果要合并可以采取(…)剩余操作符将第上层数据拿过来。案例
constructor() {super();this.state = {n: 0,m: 0,user: {name: "frank",age: 18}};}// 修改数据changeUser() {this.setState({// m 和 n 不会被置空user: {...this.state.user, // 复制之前的所有属性name: "jack"// age 被置空}});}
函数组件
const Grandson = () => {const [n, setN] = React.useState(0);const [m, setM] = React.useState(0);return (<div className="Grandson">孙子 n:{n}<button onClick={() => setN(n + 1)}>n+1</button>m:{m}<button onClick={() => setM(m + 1)}>m+1</button></div>);};
函数组件不会合并属性,案例
React事件绑定
class Son extends React.Component {addN = () => this.setState({ n: this.state.n + 1 })render() {return <button onClick={this.addN}>n+1</button>}}
