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( item ) } }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 (
    { this.state.list.map((item, index) => { return( { /** 替换li标签 */ } ) }) }
); } } 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( {this.props.value} {/**通过this.props来获取父组件传递过来的参数*/} ) } }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 (
    { this.state.list.map((item, index) => { return( {/** 通过属性传递给子组件 */}) }) }
); } } 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 (
    { this.state.list.map((item, index) => { return() }) }
); } } 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( {this.props.value} ) } }export default Item

总结
  • 通过以上几步我们以及将li拆分成一个组件了。
  • 但是在父组件传递给子组件函数的时候,需要注意一点,如果你所传递的函数是箭头函数,可以直接传递就如上面代码一样
  • 如果你所传递的函数是一个非箭头函数,需要通过bind(this)强行将这个函数的this指向父组件,不然在子组件中使用的时候this是指向子组件的,子组件是没有父组件的函数的。
  • 另外这次拆分还有一项警告没有解决index.js:1375 Warning: Each child in a list should have a unique "key" prop.
  • 下次更新

    推荐阅读