Open Skeanmy opened 4 years ago
单向数据流的props
观察者模式:自定义事件机制
调用回调:利用回调函数 子组件向父组件通信,同样也需要父组件向子组件传递props进行通讯,只是父组件传递的是作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中。
// 父组件App.js class App extends Component { constructor(props) { super(props); this.state = { msg: '父类的消息', name: 'John', age: 99 } } callback = (msg, name, age) => { // setState方法,修改msg的值,值是由child里面传过来的 this.setState({ msg }); this.setState({ name }); this.setState({ age }); } render() { return ( <div className="App"> <p> Message: {this.state.msg}</p> <Child callback={this.callback} age={this.state.age} name={this.state.name}> </Child> </div> ); } } // 子组件Child class Child extends React.Component { constructor(props) { super(props); this.state = { name: 'Andy', age: 31, msg: "来自子类的消息" } } change = () => { this.props.callback(this.state.msg, this.state.name, this.state.age); } render() { return ( <div> <div>{this.props.name}</div> <div>{this.props.age}</div> <button onClick={this.change}>点击</button> </div> ) } }
注意在子组件中change函数采用了箭头函数的写法change = () => {},目的是为了改变this的指向。使得在函数单独调用的时候,函数内部的this依然指向child组件。
change = () => {}
如果不使用箭头函数,而是采用普通的写法则需要在子组件constructor中bind一下this.change = this.change.bind(this),或者在onClick方法中绑定this, onClick={this.change=this.change.bind(this)}。在构造函数中绑定this比较节约性能。
this.change = this.change.bind(this)
onClick={this.change=this.change.bind(this)}
父组件在通过props传递操作自己state的方法时,需要把这个方法的this牢牢的绑定在自己身上
箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。 state
箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
this
构造函数是唯一可以给 this.state 赋值的地方
this.state
// 错误做法,不会重新渲染组件 this.state.comment = 'Hello'; // 正确做法 this.setState({comment: 'Hello'}); constructor(props) { super(props); this.state = {date: new Date()}; }
state的更新是可能异步的,因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
this.props
// Wrong this.setState({ counter: this.state.counter + this.props.increment, }); // Correct this.setState((state, props) => ({ counter: state.counter + props.increment }));
让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数
setState()
修改state并且获取最新state的最佳方式
handleInputChange(e) { // 异步操作state时,需要对这次的值进行保存 const { value } = e.target; this.setState(() => ({ newValue:value }), () => { // 对最新的state进行操作 }) }
在典型的 React 数据流中,props是父组件与子组件交互的唯一方式。要修改一个子组件,你需要使用新的 props 来重新渲染它。但是,在某些情况下,你需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素。
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return ( <div ref={this.myRef} /> <input ref={(ref) => {this.input = ref}}/> ); } }
ref
React.createRef()
current
setState什么时候是同步的,什么时候是异步的?
React
组件间通信
父组件向子组件的通信
单向数据流的props
子组件向父组件通信
观察者模式:自定义事件机制
调用回调:利用回调函数 子组件向父组件通信,同样也需要父组件向子组件传递props进行通讯,只是父组件传递的是作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中。
注意在子组件中change函数采用了箭头函数的写法
change = () => {}
,目的是为了改变this的指向。使得在函数单独调用的时候,函数内部的this依然指向child组件。如果不使用箭头函数,而是采用普通的写法则需要在子组件constructor中bind一下
this.change = this.change.bind(this)
,或者在onClick方法中绑定this,onClick={this.change=this.change.bind(this)}
。在构造函数中绑定this比较节约性能。父组件在通过props传递操作自己state的方法时,需要把这个方法的this牢牢的绑定在自己身上
构造函数是唯一可以给
this.state
赋值的地方state的更新是可能异步的,因为
this.props
和this.state
可能会异步更新,所以你不要依赖他们的值来更新下一个状态。让
setState()
接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数修改state并且获取最新state的最佳方式
Ref
在典型的 React 数据流中,props是父组件与子组件交互的唯一方式。要修改一个子组件,你需要使用新的 props 来重新渲染它。但是,在某些情况下,你需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素。
ref
属性用于 HTML 元素时,构造函数中使用React.createRef()
创建的ref
接收底层 DOM 元素作为其current
属性。ref
属性用于自定义 class 组件时,ref
对象接收组件的挂载实例作为其current
属性。