• react入门系列之todolist组件拆分父子组件传值


    todolist组件的拆分

    • 之前我们做的todolist,他只有一个组件。就是App.js组件。
    • 其实我们可以将input框,按钮都拆分成一个组件,每一个li也可以分成一个组件去渲染。
    • 现在我们尝试将每一个li拆成一个组件去渲染。

    第一步:在src目录下创建一个item.js

    • 代码如下
    import React, {Component, Fragment} from 'react';
    
    class Item extends Component {
        constructor(props){
            super(props);
        }
        render(){
            return(
                <Fragment>
                    <div>item</div>
                </Fragment>
            )
        }
    }
    
    export default Item
    

    第二步:将item组件引入App.js组件中

    • 将item组件引入App组件之后,将li标签替换掉
    • 代码如下
    • 此时我们每点击一次提交按钮下面就会渲染一个item标签,但是内容一直都是item,因为我们在组件中写死了内容
    import React, { Component, Fragment }from 'react';
    import Item from './item.js' // 引入item组件
    
    class App extends Component {
      constructor(props){
        super(props);
        this.state = {
          inputValue: '',// 用来存储 input框中的 value值。
          list:[] // 用来存储 每一个li的 value值。
        }
      }
      handleInputChange = (e) => {
        this.setState({
          inputValue: e.target.value
        })
        console.log(e.target)
      }
      addList = () => {
        this.setState({
          list: [...this.state.list, this.state.inputValue],
          inputValue: '' // 添加完毕以后清空input框
        })
      }
      deletListItem(index) { // 因为在绑定该方法的时候使用了bind函数,所以这里可以不实用箭头函数去保证this的指向
        console.log(index)
        let list = this.state.list;
        list.splice(index, 1);
        console.log(list)
        this.setState({
          list: [...list]
        })
      }
      render(){
        return (
          <Fragment>
          <div>
            <input
            onChange = { this.handleInputChange }
            value = {this.state.inputValue} 
            />
            <button onClick = { this.addList }>提交</button>
          </div>
          <ul>
            {
              this.state.list.map((item, index) => {
                return(
                  <Item></Item> { /** 替换li标签 */ }
                )
              })
            }
          </ul>
          </Fragment>
        );
      }
    }
    export default App;
    
    

    第三步:父组件给子组件传值

    • 上一步我们实现了item组件的拆分和引用,但是数据没有同步
    • 我们需要将父组件中inputValue传递给item组件
    • 父组件传值给子组件,是通过属性传值。子组件通过this.props去获取父组件传递值。
    • item.js代码如下
    import React, {Component, Fragment} from 'react';
    
    class Item extends Component {
        constructor(props){
            super(props);
        }
        render(){
            return(
                <Fragment>
                    <div>{this.props.value}</div> {/**通过this.props来获取父组件传递过来的参数*/}
                </Fragment>
            )
        }
    }
    
    export default Item
    
    • App.js组件代码如下
    import React, { Component, Fragment }from 'react';
    import Item from './item.js'
    
    class App extends Component {
      constructor(props){
        super(props);
        this.state = {
          inputValue: '',// 用来存储 input框中的 value值。
          list:[] // 用来存储 每一个li的 value值。
        }
      }
      handleInputChange = (e) => {
        this.setState({
          inputValue: e.target.value
        })
        console.log(e.target)
      }
      addList = () => {
        this.setState({
          list: [...this.state.list, this.state.inputValue],
          inputValue: '' // 添加完毕以后清空input框
        })
      }
      deletListItem(index) { // 因为在绑定该方法的时候使用了bind函数,所以这里可以不实用箭头函数去保证this的指向
        console.log(index)
        let list = this.state.list;
        list.splice(index, 1);
        console.log(list)
        this.setState({
          list: [...list]
        })
      }
      render(){
        return (
          <Fragment>
          <div>
            <input
            onChange = { this.handleInputChange }
            value = {this.state.inputValue} 
            />
            <button onClick = { this.addList }>提交</button>
          </div>
          <ul>
            {
              this.state.list.map((item, index) => {
                return(
    
                  <Item 
                  value={item} 
                  deletItem = {this.state.deletListItem}
                  ></Item> {/** 通过属性传递给子组件 */}
    
                )
              })
            }
          </ul>
          </Fragment>
        );
      }
    }
    export default App;
    
    

    第四步:子组件给父组件传值

    • 上一步通过父组件传值给子组件,我们解决了增加的功能,让item的value能同步input提交的数据
    • 现在我们需要完成删除的功能,删除我们需要将item的key值传递给父组件,让他删除list数组中对应的元素
    • 如何达到效果呢,我们还是需要父组件将删除的方法传递给子组件,再在子组件中去执行他
    • App.js代码如下
    import React, { Component, Fragment }from 'react';
    import Item from './item.js'
    
    class App extends Component {
      constructor(props){
        super(props);
        this.state = {
          inputValue: '',// 用来存储 input框中的 value值。
          list:[] // 用来存储 每一个li的 value值。
        }
      }
      handleInputChange = (e) => {
        this.setState({
          inputValue: e.target.value
        })
        console.log(e.target)
      }
      addList = () => {
        this.setState({
          list: [...this.state.list, this.state.inputValue],
          inputValue: '' // 添加完毕以后清空input框
        })
      }
      deletListItem = (index) => { // 因为在绑定该方法的时候使用了bind函数,所以这里可以不实用箭头函数去保证this的指向
        console.log(index)
        let list = this.state.list;
        list.splice(index, 1);
        console.log(list)
        this.setState({
          list: [...list]
        })
      }
      render(){
        return (
          <Fragment>
          <div>
            <input
            onChange = { this.handleInputChange }
            value = {this.state.inputValue} 
            />
            <button onClick = { this.addList }>提交</button>
          </div>
          <ul>
            {
              this.state.list.map((item, index) => {
                return(
    
                  <Item 
                  value = {item} 
                  index = {index}
                  deletItem = {this.deletListItem}
                  ></Item>
    
                )
              })
            }
          </ul>
          </Fragment>
        );
      }
    }
    export default App;
    
    • item.js代码如下
    import React, {Component, Fragment} from 'react';
    
    class Item extends Component {
        constructor(props){
            super(props);
        }
        deletItem = () => {
            this.props.deletItem(this.props.index)
            console.log(this.props.index)
        }
        render(){
            return(
                <Fragment>
                    <div
                    onClick = {this.deletItem}
                    >
                    {this.props.value}
                    </div>
                </Fragment>
            )
        }
    }
    
    export default Item
    

    总结

    • 通过以上几步我们以及将li拆分成一个组件了。
    • 但是在父组件传递给子组件函数的时候,需要注意一点,如果你所传递的函数是箭头函数,可以直接传递就如上面代码一样
    • 如果你所传递的函数是一个非箭头函数,需要通过bind(this)强行将这个函数的this指向父组件,不然在子组件中使用的时候this是指向子组件的,子组件是没有父组件的函数的。
    • 另外这次拆分还有一项警告没有解决index.js:1375 Warning: Each child in a list should have a unique "key" prop.
    • 下次更新
  • 相关阅读:
    线程的异常捕获与线程池的异常捕获
    设计模式-状态模式
    老王讲自制RPC框架.(四.序列化与反序列化)
    老王讲自制RPC框架.(三.ZOOKEEPER)
    老王讲自制RPC框架.(二.动态代理)
    4
    3
    2
    1
    前言
  • 原文地址:https://www.cnblogs.com/boye-1990/p/11365688.html
Copyright © 2020-2023  润新知