React 组件通信

2019-11-08  本文已影响0人  张思学

组件通讯是单向的,数据必须是由一方传到另一方。
1:父组件可以向子组件通过传 props 的方式,向子组件进行通讯。
2:子组件向父组件通讯,也需要父组件向子组件传递 props 进行通讯,只是父组件传递的是父组件自身的函数,子组件调用该函数,将子组件想要传递的信息作为参数,传递到父组件的作用域方法中。

就拿 数据绑定 和 事件绑定内篇文档的代码进行举例
  1. index.js 入口文件引入组件(这里的组件指的是父组件)
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'; //导入TodoList组件

ReactDOM.render(
  <TodoList/>,
  document.getElementById('root')
);
  1. src目录下新建 TodoList.js 注释里有父组件传递数据给子组件的说明
import React, {Component, Fragment} from 'react'
import TodoItem from "./TodoItem"; //导入子组件 TodoItem

class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: '',
      list: ['星期一', '星期二', '星期三']
    }
    //对方法的this指向进行修改
    this.inputChange = this.inputChange.bind(this)
    this.setInputChange = this.setInputChange.bind(this)
    this.delListItem = this.delListItem.bind(this)
  }

  render() {
    return (
      <Fragment>
        <div>
          <input
            value={this.state.inputValue}
            onChange={this.inputChange}/>
          <button onClick={this.setInputChange}>提交</button>
        </div>
        <ul>
          {this.getTodoItem()} {/*执行方法会返回 jsx 模版*/}
        </ul>
      </Fragment>
    )
  }

  getTodoItem() {
    return this.state.list.map((item, index) => {
      return (
        /* 数据传递:
         * 把要传递的数据值通过(自定义命名)
         * content, index 传递值给子组件
         * deleteItem 传递父组件方法给子组件 ,传递的方法一定要做this属性指向
         */
        <TodoItem
          key={index}
          content={item}
          index={index}
          deleteItem={this.delListItem}
        />
      )
    });
  }

  inputChange(e) {
    /* this.setState可以也接收一个函数
     * 这个函数有一个返回值 return {} 返回一个对象, ES6里返回一个对象可以使用简写 ({})
     */
    const value = e.target.value
    this.setState(() => ({
      inputValue: value
    }));
  }

  setInputChange() {
    /* setState 可以接收一个参数 prevState
     * prevState 指的是你修改数据之前的内一次数据是什么样的, 它等价于this.state
     */
    this.setState((prevState) => ({
      list: [...prevState.list, prevState.inputValue],
      inputValue: ''
    }));
  }

  delListItem(index) {
    this.setState((prevState) =>{
      const list = [...prevState.list]
      list.splice(index, 1)
      return {
        list
      }
    });
  }
}

export default TodoList;

3、src目录下新建TodoItem.js 注释里有子组件使用父组件方法并改变数据的说明

import React, {Component} from 'react'

class TodoItem extends Component {
  constructor(props) {
    super(props)
    this.del = this.del.bind(this)
  }

  render() {
    const { content } = this.props  //ES6 语法定义变量 等价于 this.props.content
    return (
      <li>
        {content} 
        <button onClick={this.del}>删除</button>
      </li>
    )
  }

  del() {
    //通过 this.props.方法名来调用父组件方法,父组件内存在改变数据的代码
    const { deleteItem, index } = this.props
    deleteItem(index)
  }
}

export default TodoItem
上一篇下一篇

猜你喜欢

热点阅读