Sui Move 前端共学笔记(四)-状态提升(中间人通信)

120 阅读2分钟

HOH水分子社区,是一个专注于编程、教育和创新的社区。

需求:

1736236245062.png

有三个组件分别为首页,电影,概述信息,关系如上图所示,电影组件中调用电影数据接口,获取信息展示如下图电影组件,点击电影相关信息后,在概述信息组件中更新当前电影概述。

image.png

代码编写

入口初始化

constructor() {
// 用于初始化类组件的状态
    super();
    this.state={
        filmList:[],
        filmDetail:"",
    }
    // 定义状态filmList用于存储电影列表数据,filmDetail用户存储电影概要信息。
    axios.get("/test.json").then(
        res => {
            console.log(res.data.data.films);
            this.setState({filmList:res.data.data.films});
        }
    )
    // 调用接口获取电影列表信息存储在filmList状态中。
}

电影组件

class FilmList extends Component{
// 定义电影组件FilmList
    render() {
        let {name,poster,grade,synopsis }=this.props
        // 解构属性,这个属性是axios接口调用后获取的列表,列表中有name(电影名称)、poster(电影图片)、grade(电影评分)、sysnopsis(电影概述)
        return (
            <div className={"filmItem"} onClick={()=>{
                this.props.onEvent(synopsis);
            }}>
            // className用于修改样式,绑定点击事件,当点击div盒子时,调用函数onEvent,这个函数通过父组件传入,在下面入口函数中会说明。
                <img src={poster} alt={name}/>
                <h4>{name}</h4>
                <div>观众评分:{grade}</div>
                // 展示图片、电影名称以及评分信息。
            </div>
        )
    }
}

电影概述组件

class FilmDetail extends Component{
// 定义电影概述组件
    render() {
        return (
            <div className={"filmDetail"}>
            // 引用样式filmDetail
                {this.props.fileDetail}
                // fileDetail为电影概述通过父组件传入。
            </div>
        )
    }
}

首页组件

···省略初始化部分,在入口初始化有说明。
render() {
    return (
        <div>
            {this.state.filmList.map(item=>
            <FilmList key={item.filmId} {...item} onEvent={(value)=>{
                // console.log(fileDetail);
                this.setState({filmDetail:value});
            }}></FilmList>
            // 将filmList映射为FilmList组件,属性传入了展开后的电影列表,和一个onEvent函数,当onEvent函数触发时,修改状态filmDetail的值,然后将这个值传入FilmDetail组件,从而实现点击电影相关信息后,在概述信息组件中更新当前电影概述。
            )}

            <FilmDetail fileDetail={this.state.filmDetail}/>
            // 概述信息组件,当filmdetail状态发生变化后会同步渲染。
        </div>
    );
}

CSS

.filmItem img{
    width:100px;
    float:left;
}

.filmItem {
    overflow: hidden;
    padding: 10px;
}

.filmDetail{
    position: fixed;
    right: 30%;
    top:100px;
    background-color: lightblue;
    width: 500px;
    height: 500px;
}

总述

在这个案例中,电影组件和概述信息,都属于首页组件的子组件,需求时点击电影组件,同步修改概述组件,但是这两个组件属于并列关系,不能直接通信,所以在这里首先使用父子通信,当电影组件内容被点击时,调用onEvent告诉父组件,有内容被点击了,然后父组件接收到事件后,修改filmDetail的值,此时由于FilmDetail状态发生变化,再次触发父子通信,父组件通知电影概述组件,重新渲染。整个过程,父组件充当中间人,所以也称为中间人通信。

效果展示

首页

image.png

点击任意电影展示概述信息

image.png

Contact US

HOH水分子公众号 Alya @HOH Jane @HOH