手记

【备战春招】第6天 React零基础入门到实战,完成企业级项目简书网站开发——React基础篇

课程名称

课程章节

第3章 React基础精讲
-3-5 拆分组件与组件之间的传值 (24:29)

课程讲师

课程内容

  • 拆分组件与组件之间的传值
    拆分TodoList的组件 =>
    ● 上面的内容:输入内容、input框、提交按钮
    ● 下面的内容:list
    列表组件 => TodoItem

  • 组件化的思想

  • 父组件向子组件传递数据
    TodoItem组件实际上,是需要获取到我们在input输入的内容,然后显示出来的。
    这就需要父组件向子组件传递显示的数据了,这样的话,子组件才能做灵活的显示了。父组件需要通过属性的方式进行传递,将item起名叫content传递给子组件。
    子组件通过this.props获取并使用即可。
    原理:当在input里提交数据时,对应数组中也会增加该数据,这个时候render函数会重新去执行,即进行页面的重新渲染,就会把item传递通过content给子组件TodoItem的props属性。

  • 子组件向父组件传递数据

课程收获

拆分组件与组件之间的传值
一个大的页面,操作逻辑就会比较复杂。如果将一个大的页面拆分成很多个组件,那么单个组件的操作逻辑就较为简答了。
拆分TodoList的组件 =>
● 上面的内容:输入内容、input框、提交按钮
● 下面的内容:list
列表组件 => TodoItem

import React, {Component} from "react";

class TodoItem extends Component{
    render(){
        return(
            <div>TodoItem</div>
        )
    }
}

export default TodoItem;

父组件TodoList去使用TodoItem组件,需要引入import,之前在ul中循环list数据,创建li标签。现在不渲染li标签了,而是渲染TodoItem标签。

...
import TodoItem from "./TodoItem"
...
render(){
        return (
            <Fragment>
                <div>
                    <label htmlFor="InputArea">输入内容</label>
                    <input
                        id="InputArea" 
                        className="input"
                        value={this.state.inputValue}
                        onChange={this.handleInputChange.bind(this)}
                    ></input>
                    <button onClick={this.handleBtnClick.bind(this)}>提交</button>
                </div>
                <ul>
                    {
                        this.state.list.map((item,index) => {
                            // return <li 
                            // key={index} 
                            // onClick={this.handleDelItem.bind(this, index)}
                            // dangerouslySetInnerHTML={{__html:item}}
                            // ></li>
                            return <TodoItem/>
                        })
                    }
                </ul>
            </Fragment>
        )
    }

现在输入内容也不管用了,显示的都是TodoItem组件了。

实际上写一个React项目时,使用组件化的思想,一般结构如下:
在最顶部有一个组件,对应这个项目,其实就是TodoList组件,下一层的组件就是TodoItem组件。实际上,当项目开始复杂后,TodoItem组件还可以向下拆分成更多的组件,这样子组件就越来越多,实际组件化思想开发,项目的组件结构就是一个树型的结构了。

父组件向子组件传递数据
TodoItem组件实际上,是需要获取到我们在input输入的内容,然后显示出来的。
这就需要父组件向子组件传递显示的数据了,这样的话,子组件才能做灵活的显示了。父组件需要通过属性的方式进行传递,将item起名叫content传递给子组件。

return <TodoItem content={item}/>

子组件通过this.props获取并使用即可。

class TodoItem extends Component{
    render(){
        return(
            <div>{this.props.content}</div>
        )
    }
}


原理:当在input里提交数据时,对应数组中也会增加该数据,这个时候render函数会重新去执行,即进行页面的重新渲染,就会把item传递通过content给子组件TodoItem的props属性。

子组件向父组件传递数据
实现:点击list的时候,列表项能够从列表中删除。
这就需要绑定一个事件了,不是给TodoItem绑定事件,还是进该组件里绑定事件,即div标签。
列表中显示项,是通过list数组渲染出来的,删除功能实际是操作删除数组里的对应项。

子组件如何去修改父组件的数据呢?
实际不允许子组件直接修改父组件的,而是通过调用父组件的方法。
之前实现的删除方法,参数是index,那么在子组件中是需要传递index的,可通过父组件传递index到子组件,子组件再调用父组件方法时传参即可。
this.handleClick.bind(this) 这种绑定事件处理函数的方法,后期很浪费性能,可以这样写:

    constructor(props){
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

ind 的操作放在构造函数里去做,省去多次render每次都bind了,这样就节约了一些性能。
子组件想改变父组件的内容,则需要调用父组件的handleDelItem(index)方法,并传递参数。
父组件应当把它自己的方法传递给子组件。

import React, { Component, Fragment } from "react";
import "./style.css"
import TodoItem from "./TodoItem"

class TodoList extends Component {
    constructor(props){
        super(props);

        this.state = {
            inputValue: "",
            list: ["完成数学作业","完成语文作业"]
        }
    }

    render(){
        return (
            <Fragment>
                <div>
                    <label htmlFor="InputArea">输入内容</label>
                    <input
                        id="InputArea" 
                        className="input"
                        value={this.state.inputValue}
                        onChange={this.handleInputChange.bind(this)}
                    ></input>
                    <button onClick={this.handleBtnClick.bind(this)}>提交</button>
                </div>
                <ul>
                    {
                        this.state.list.map((item,index) => {
                            return <TodoItem 
                            content = {item}  
                            index = {index} 
                            deleteItem = {this.handleDelItem}
                            />
                        })
                    }
                </ul>
            </Fragment>
        )
    }

    handleInputChange(e){
        // console.log(this)
        // this.state.inputValue = e.target.value;
        this.setState({
            inputValue: e.target.value
        })
    }

    handleBtnClick(){
        this.setState({
            list:[...this.state.list, this.state.inputValue],
            inputValue:""
        })
    }
    handleDelItem(index){
        const dest = [...this.state.list];
        dest.splice(index, 1);

        // this.state.list.splice(index, 1);

        this.setState({
            list: dest
            // list: this.state.list
        })
    }
}

export default TodoList;
import React, {Component} from "react";

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

    render(){
        return(
            <div onClick={this.handleClick}>{this.props.content}</div>
        )
    }

    handleClick(){
        this.props.deleteItem(this.props.index);
    }
}

export default TodoItem;

点击列表项,报错了。

因为传递的方法this,到了子组件时候当前this下就没有deleteItem方法了,这个时候就需要this指向,指向父组件了。

                <ul>
                    {
                        this.state.list.map((item,index) => {
                            // return <li 
                            // key={index} 
                            // onClick={this.handleDelItem.bind(this, index)}
                            // dangerouslySetInnerHTML={{__html:item}}
                            // ></li>
                            return <TodoItem 
                            content = {item}  
                            index = {index} 
                            deleteItem = {this.handleDelItem.bind(this)}
                            />
                        })
                    }
                </ul>

总结
● 组件拆分
● 父子组件的关系,数据相互传递
○ 父 => 子,可以传递数据,也可方法
○ 子 => 父,调用父组件的方法来操作父组件的数据,注意父组件的this指向一定进行绑定。


0人推荐
随时随地看视频
慕课网APP