React(5)

1.受控组件案例

1.1之前的影院案例改写

import React, { Component } from 'react'
import axios from 'axios'
import BetterScroll from 'better-scroll'
import './css/02_tab.css'

export default class Cinema extends Component {


    constructor() {
        super();
        this.state = {
            cinemaList: [],
            mytext:''
            // backcinemaList: []
        }
        //react中使用axios第三方的库  专门用来请求数据
        // axios.get("请求地址").then(res=>{}).catch(err=>{console.log(err);})
        axios({
            url: "https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=7406159",
            method: 'get',
            headers: {
                'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"16395416565231270166529","bc":"110100"}',
                'X-Host': 'mall.film-ticket.cinema.list'
            }
        }).then(res => {
            console.log(res.data)
            this.setState({
                cinemaList: res.data.data.cinemas,
                // backcinemaList: res.data.data.cinemas
            })

            new BetterScroll(".wrapper")
        }).catch(err => console.log(err))


    }

    render() {
        return (
            <div>
                <div>
                    {/* <input onInput={this.handleInput}></input>实时搜索 */}
                    <input value={this.state.mytext} onChange={(evt)=>{
                        this.setState({
                            mytext:evt.target.value
                        },()=>{
                            console.log(this.state.mytext);
                        })
                       
                    }}></input>实时搜索
                </div>

                <div className='wrapper' style={{height:'800px',overflow:'hidden'}}>
                    <div className='content'>
                        {
                            this.getCinemaList().map((item) =>
                                <dl key={item.cinemaId}>
                                  <dt>{item.name}</dt>
                                    <dd>{item.address}</dd>
                                </dl>
                           )
                        }
                    </div>
                </div>

            </div>
        )
    }

    getCinemaList=()=>{
        //return this.state.cinemaList
        return this.state.cinemaList.filter(item => 
            item.name.toUpperCase().includes(this.state.mytext.toUpperCase()) ||
            item.address.toUpperCase().includes(this.state.mytext.toUpperCase()))
    }

    // handleInput = (event) => {
    //     console.log("input", event.target.value);
    //     // 数组的filter方法不会影响原数组
    //     var newList = this.state.backcinemaList.filter(item => item.name.toUpperCase().includes(event.target.value.toUpperCase()) ||
    //         item.address.toUpperCase().includes(event.target.value.toUpperCase()))
    //     this.setState({
    //         cinemaList: newList
    //     })
    // }
}

1.2 todolist改写


import React, { Component } from 'react'

export default class App extends Component {

    constructor() {
        super();
        this.state = {
            addList: [
                {
                    id: Math.random()*10000, 
                    title: "张三"
                }
            ],
            mytext:''
        }

    }

    //myref = React.createRef();

    render() {
        return (
            <div>
                <input value={this.state.mytext} onChange={(evt)=>{
                     this.setState({
                        mytext:evt.target.value
                    })
                }}></input>
                <button onClick={() => {
                    this.handler()
                }}>增加</button>
                <ul>
                    {
                        this.state.addList.map((item,index) =>
                            <li key={item.id}>
                                {/* {item.id}----{item.title} */}
                                <span dangerouslySetInnerHTML={
                                    {
                                        __html:item.id+"------"+item.title
                                    }
                                }></span>

                                <button onClick={()=>{
                                    this.deleteList(index)
                                }}>删除</button>
                            </li>
                            )
                    }
                </ul>
                {/* {this.state.addList.length===0 ?<div>暂无待办事项</div>:null} */}
                {this.state.addList.length===0 && <div>暂无待办事项</div>}
            </div>
        )
    }

    handler = () => {
        let newList = [...this.state.addList]
        newList.push(
            {
                id: Math.random()*10000,
                title: this.state.mytext
            }
        )
        this.setState({
            addList: newList,
            mytext:''
        }) 

    }

    deleteList=(index)=>{
        console.log(index);
        let newList = [...this.state.addList];
        newList.splice(index,1);//从该下标开始删除  删除一个
        this.setState({
            addList: newList
        })
    }
}

2.父子通信

场景:比如我有一个父组件   父组件内部有1个导航组件  一个侧边栏组件   在导航栏组件中,我做了一个操作后,想让侧边栏组件隐藏与显示    

这就需要子传父了   导航栏组件传递信号给父组件  父组件再去控制侧边栏组件

例如:

父组件

通过state中的isShow来控制侧边栏组件的显示

import React, { Component } from 'react'
import Navbar from './compoent/Navbar'
import SideBar from './compoent/SideBar'


export default class App extends Component {

    state={
        isShow:true,
    }


    render() {
        return (
            <div>           
                <Navbar/>

                {this.state.isShow && <SideBar/>}
            </div>
        )
    }
}

侧边栏组件

import React, { Component } from 'react'

export default class SideBar extends Component {
    render() {
        return (
            <div style={{background:"green",width:"300px"}}>
                <ul>
                    <li>11111</li>
                    <li>11111</li>
                    <li>11111</li>
                    <li>11111</li>
                    <li>11111</li>
                    <li>11111</li>
                    <li>11111</li>
                </ul>
            </div>
        )
    }
}

导航栏组件

import React, { Component } from 'react'

export default class Navbar extends Component {
    render() {
        return (
            <div style={{background:"yellow",width:"400px"}}>
                <button>控制侧边栏</button>

            </div>
        )
    }
}

 现在需要去做修改,使用event属性传一个回调函数,然后子组件中调用此函数

可以发现子组件中点击按钮后,已经可以控制父组件中打印了。因此咱后面可以在父组件中修改state中的值了

export default class App extends Component {

    state={
        isShow:true,
    }


    render() {
        return (
            <div>           
                <Navbar event={()=>{
                    console.log("父组件中可以修改state了");
                    this.setState({
                        isShow:!this.state.isShow
                    })
                }}/>

                {this.state.isShow && <SideBar/>}
            </div>
        )
    }
}

总结:

父传子:传属性

子传父:父给子一个函数,子执行此函数  当成回调函数

3.父子通信版:表单域组件


import React, { Component } from 'react'
import Field from './compoent/Field'

export default class App extends Component {

    state={
        username:"",
        password:""
    }

    render() {
        return (
            <div>
                <Field label="用户名" type="text" value={this.state.username} onChangeEvent={(value)=>{
                    // console.log("value==="+value);
                    this.setState({
                        username:value
                    })
                }}></Field>
                <Field label="密码" type="password" value={this.state.password} onChangeEvent={(value)=>{
                    // console.log("value==="+value);
                    this.setState({
                        password:value
                    })
                }}></Field>
                
                <button onClick={()=>{
                    console.log(this.state.username+"\t"+this.state.password+"发送给后端校验");
                }}>登录</button>
                
                <button onClick={()=>{
                    this.setState({
                        username:"",
                        password:""
                    })
                }}>重置</button>
            </div>
        )
    }
}


import React, { Component } from 'react'

export default class Field extends Component {
    render() {
        return (
            <div>
                <label>{this.props.label}</label>
                <input type={this.props.type} value={this.props.value} onChange={(evt)=>{
                    // console.log(evt.target.value);
                    this.props.onChangeEvent(evt.target.value);

                }}></input>
            </div>
        )
    }
}

4.ref版:表单域组件


import React, { Component } from 'react'
import Field2 from './compoent/Field2'

export default class App extends Component {

    username=React.createRef();
    password=React.createRef();

    render() {
        return (
            <div>
                <Field2 label="用户名" type="text" ref={this.username}></Field2>
                <Field2 label="密码" type="password" ref={this.password}></Field2>
                
                <button onClick={()=>{
                    console.log(this.username);  //可以发现这里拿到的是Field2这个组件
                    console.log(this.username.current.state.value+"\t"+this.password.current.state.value+"发送给后端校验");
                }}>登录</button>
                
                <button onClick={()=>{
                    this.username.current.clear();
                    this.password.current.clear();
                }}>重置</button>
            </div>
        )
    }
}


import React, { Component } from 'react'

export default class Field2 extends Component {

    state={
        value:""
    }

    clear(){
        this.setState({
            value:""
        })
    }

    render() {
        return (
            <div>
                <label>{this.props.label}</label>
                <input type={this.props.type}  value={this.state.value} onChange={(evt)=>{
                    this.setState({
                        value:evt.target.value
                    })
                }}></input>
            </div>
        )
    }
}

   console.log(this.username);  //可以发现这里拿到的是Field2这个组件

5.非父子通信方式

5.1 状态提升(中间人模式)

React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上。在父组件上改变这个状态然后通过props分发给子组件。

案例数据:

[
			{
				"filmId": 6464,
				"name": "孤注一掷",
				"poster": "https://pic.maizuo.com/usr/movie/6055722f845f73ab45d5d77d58fc2ea1.jpg",
				"actors": [
					{
						"name": "申奥",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/6aa3e66baa1f13870bfd8d6de81e5269.png"
					},
					{
						"name": "张艺兴",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/0f522f3e4bd18e496d97e8c17c05bfc1.png"
					},
					{
						"name": "金晨",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/789399740eb132d44325ba8c3c8d048e.jpeg"
					},
					{
						"name": "咏梅",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/390a71eaeca70de6bbeb2fb2f4dd12d7.jpg"
					},
					{
						"name": "王传君",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/770f8b42d9304c75c16cb7419eed78a0.jpg"
					}
				],
				"director": "申奥",
				"category": "犯罪|剧情",
				"synopsis": "电影取材自上万起真实诈骗案例,境外网络诈骗全产业链骇人内幕将在大银幕上首度被揭秘。程序员潘生(张艺兴 饰)、模特安娜(金晨 饰)被海外高薪招聘吸引,出国淘金,却意外落入境外诈骗工厂的陷阱。为了离开,两人准备向赌徒阿天(王大陆 饰)和其女友小雨(周也 饰)下手,从他们身上套现、完成业绩……潘生与安娜能否逃过诈骗集团头目陆经理(王传君 饰)和阿才(孙阳 饰)的残暴折磨?面对警察(咏梅 饰)的跨国调查和追捕,他们又会何去何从?",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1691712000,
				"timeType": 3,
				"runtime": 130,
				"grade": "7",
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6429,
				"name": "封神第一部:朝歌风云",
				"poster": "https://pic.maizuo.com/usr/movie/f57040d1983ab2923e53aedb36a00cd4.jpg",
				"actors": [
					{
						"name": "乌尔善",
						"role": "导演/创意制片人",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/45c0074aee9ede6cbdaa92441291ea4c.jpg"
					},
					{
						"name": "费翔",
						"role": "商王殷寿",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/faa37b41f5a372cafe14348b571c42ae.jpg"
					},
					{
						"name": "李雪健",
						"role": "西伯侯姬昌",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/6c377dc94628b41e23c924da29cc7ced.jpg"
					},
					{
						"name": "黄渤",
						"role": "姜子牙",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/f2a4a18bf8cf420b09c0a19d20a4a0fc.jpg"
					},
					{
						"name": "于适",
						"role": "姬发",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/a05e6c02e6f5df195369793ba45a82d1.jpg"
					}
				],
				"director": "乌尔善",
				"category": "神话|动作|史诗",
				"synopsis": "中国国民神话史诗大片,震撼视效燃炸暑期!《封神第一部》讲述商王殷寿勾结狐妖妲己,暴虐无道,引发天谴。昆仑仙人姜子牙携“封神榜”下山,寻找天下共主,以救苍生。西伯侯之子姬发逐渐发现殷寿的本来面目,反出朝歌。各方势力暗流涌动,风云变幻端倪初显……三千年想象成真,恢弘史诗再创新,见证中国神话崛起!",
				"filmType": {
					"name": "4D",
					"value": 13
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1689811200,
				"timeType": 3,
				"runtime": 148,
				"grade": "7.4",
				"item": {
					"name": "4D",
					"type": 13
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6458,
				"name": "巨齿鲨2:深渊",
				"poster": "https://pic.maizuo.com/usr/movie/ff0c6346f478b8cec25ee1ba25789087.jpg",
				"actors": [
					{
						"name": "本·维特利",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/83430205d4c2d81f34e40a125b5bc4c2.jpg"
					},
					{
						"name": "杰森·斯坦森",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/6dd461c2302409b5db39a7bbb0d54dc1.jpg"
					},
					{
						"name": "吴京",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/80f93f06a5fcbbbf0a9085125b2a93b2.jpg"
					},
					{
						"name": "蔡书雅",
						"role": "Meiying",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/57c4dfb0c05587e2451539e40216696b.jpg"
					},
					{
						"name": "克利夫·柯蒂斯",
						"role": "James 'Mac' Mackreides",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/2c96c58b26df9239212922e2999ea5b0.jpg"
					}
				],
				"director": "本·维特利",
				"category": "冒险|动作|科幻",
				"synopsis": "海洋霸主巨齿鲨,今夏再掀狂澜!乔纳斯·泰勒(杰森·斯坦森 饰)与科学家张九溟(吴京 饰)双雄联手,进入海底7000米深渊执行探索任务。他们意外遭遇史前巨兽海洋霸主巨齿鲨群的攻击,还将对战凶猛危险的远古怪兽群。惊心动魄的深渊冒险,巨燃巨爽的深海大战一触即发……",
				"filmType": {
					"name": "4D",
					"value": 13
				},
				"nation": "中国大陆,美国",
				"language": "",
				"videoId": "",
				"premiereAt": 1691107200,
				"timeType": 3,
				"runtime": 116,
				"grade": "7.4",
				"item": {
					"name": "4D",
					"type": 13
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6475,
				"name": "学爸",
				"poster": "https://pic.maizuo.com/usr/movie/756acd186a52bef02d9b06a0e1f059c5.jpg",
				"actors": [
					{
						"name": "苏亮",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/31bdfb025fc6c3d9a18dcc5a99273826.jpg"
					},
					{
						"name": "黄渤",
						"role": "雷大力",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/f2a4a18bf8cf420b09c0a19d20a4a0fc.jpg"
					},
					{
						"name": "单禹豪",
						"role": "雷小米",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/45ad82f78680568b4e4b356934a40fa6.jpg"
					},
					{
						"name": "闫妮",
						"role": "刘真真",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/d760dccb352ace3cf12b9a69d457d786.jpg"
					},
					{
						"name": "张钧甯",
						"role": "高亚琳",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/57970a3dd17cca49a87a9ea653aeffaf.jpg"
					}
				],
				"director": "苏亮",
				"category": "剧情|家庭",
				"synopsis": "黄渤强势回归现实主义题材,演绎小人物的命运与挣扎,展现中国万千家庭面貌,“卷不动又躺不平”的人生百态直击人心!雷大力(黄渤 饰)为了让儿子雷小米(单禹豪 饰)能够拥有更高的人生起点,在单亲妈妈刘真真(闫妮 饰)的带领下,被迫卷入了“幼升小”的激烈角逐。又在火哥(张子贤 饰)和火嫂(万茜 饰)的影响下,不惜倾尽所有购入学区房,重重压力让父子二人的生活变得不堪一击。雷小米小姨(张钧甯 饰)的出现,又让雷大力领悟了“拼娃”的本质是“拼父母”……面对残酷的现实,父子的生活困境应该如何破局?几组家庭又将做出怎样的人生抉择?",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1692316800,
				"timeType": 3,
				"runtime": 118,
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 5770,
				"name": "暗杀风暴",
				"poster": "https://pic.maizuo.com/usr/movie/537d2d8635a6ce61058940460eda2378.jpg",
				"actors": [
					{
						"name": "张智霖",
						"role": "罗飞",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/8ac5d5d1c5b227515f55a0ecf365f87a.jpg"
					},
					{
						"name": "吴镇宇",
						"role": "韩灏",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/39d3432ff8c97c8bdc0f7e8fa6d164a4.jpg"
					},
					{
						"name": "胡杏儿",
						"role": "孟芸",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/1b71d1a4843fb95bb3a2abd35014d8d3.jpg"
					},
					{
						"name": "邱礼涛",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/03f51d6fde99eaa0a39cbc5db3d6514b.jpg"
					},
					{
						"name": "古天乐",
						"role": "黄少平",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/eeed4920326e45a1b4f9a2a0425ad8ef.jpg"
					}
				],
				"director": "邱礼涛",
				"category": "悬疑|犯罪",
				"synopsis": "改编自周浩晖豆瓣高分悬疑小说,尺度大开、高能反转!以“审判者”自居的神秘杀手Darker公开挑衅警方,接连发出“死亡通知单”,收到之人都会被残忍处决。为查清真相,爆炸案目击者黄少平(古天乐 饰)、天才警察罗飞(张智霖 饰)、专案组组长韩灏(吴镇宇 饰)纷纷入局。Darker究竟是谁?真相不断反转,惊人的秘密逐渐浮出水面……",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1692316800,
				"timeType": 3,
				"runtime": 100,
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6460,
				"name": "我经过风暴",
				"poster": "https://pic.maizuo.com/usr/movie/e1153c4e9376295cd55e0fe2b484f391.jpg",
				"actors": [
					{
						"name": "秦海燕",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/e5d0caa847b120434a72bc8135013d1a.jpg"
					},
					{
						"name": "佟丽娅",
						"role": "徐敏",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/89d4bb6e9cfdb2ac41925a1aa5364fd1.jpg"
					},
					{
						"name": "吴昱翰",
						"role": "陈均",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/f53162cfd562abbed3f742cbb9c7f212.jpg"
					},
					{
						"name": "王影璐",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/03d93bae2974d595793f1004712ca00c.jpg"
					},
					{
						"name": "姜瑞霖",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/ec4296157666f4542c60f6578278fb06.jpg"
					}
				],
				"director": "秦海燕",
				"category": "剧情|家庭",
				"synopsis": "在中国,平均每7.4秒就有一位女性遭受家暴。看似强势独立的徐敏(佟丽娅 饰)有着难以启齿的秘密:她被丈夫陈均(吴昱翰 饰)长期家暴。徐敏不是所有人想象中受害者的模样,她坚毅勇敢且有自己的事业,在与律师李小萌(王影璐 饰)艰难抗争试图离婚的过程中,面对小心谨慎不留证据的丈夫、周遭人冷言冷语嘲讽质疑、社会系统的不作为、为了两个孩子…当离婚不是家暴的终点,当家不是避风港而是暴雨本身,她究竟能否冲破这场风暴?",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1692230400,
				"timeType": 3,
				"runtime": 101,
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6435,
				"name": "热烈",
				"poster": "https://pic.maizuo.com/usr/movie/7a65ca156d207509f2105b3b1a48c154.jpg",
				"actors": [
					{
						"name": "大鹏",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/75741ac19a8019deccf3a9ba8709dc49.jpg"
					},
					{
						"name": "黄渤",
						"role": "丁雷",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/f2a4a18bf8cf420b09c0a19d20a4a0fc.jpg"
					},
					{
						"name": "王一博",
						"role": "陈烁",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/fd239dabe7f2045116bff76b8be42e91.jpg"
					},
					{
						"name": "刘敏涛",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/4bf2ab2c8af097c628c24f7340e7e461.jpg"
					},
					{
						"name": "岳云鹏",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/40e42ee733fcbc8e1c2a1666022e334f.jpg"
					}
				],
				"director": "大鹏",
				"category": "青春|励志|剧情",
				"synopsis": "街舞老炮儿丁雷,偶遇卖艺少年陈烁,丁雷忽悠陈烁加入自己经营的舞团。舞团内高手如云,性格各异,与陈烁碰撞出不同的火花,笑料不断。陈烁热烈追梦,期待着上场的机会,却发现丁雷邀请他其实另有目的,而丁雷和陈烁,也都将面对接二连三的沉重打击,他们能否逆风翻盘,回击人生难题?",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1690502400,
				"timeType": 3,
				"runtime": 124,
				"grade": "7.2",
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6427,
				"name": "长安三万里",
				"poster": "https://pic.maizuo.com/usr/movie/1a1374d8f4add341468aa6a5ca3aa9f4.jpg",
				"actors": [
					{
						"name": "谢君伟",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/838e207c7797b6b2dbd4d91eb394c8e8.jpeg"
					},
					{
						"name": "邹靖",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/84368a3cd34795987ad144d80978532e.jpeg"
					},
					{
						"name": "杨天翔",
						"role": "配音演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/400df217f4fe41b8d17e9807de2bf812.jpeg"
					},
					{
						"name": "凌振赫",
						"role": "配音演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/f2897608fdf77c764383dac4b66c6f06.jpg"
					},
					{
						"name": "吴俊全",
						"role": "配音演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/40ff6adb6fd29d1acceb1959b028fa9f.jpg"
					}
				],
				"director": "谢君伟|邹靖",
				"category": "历史|动画",
				"synopsis": "安史之乱爆发后数年,吐蕃大军攻打西南。大唐节度使高适交战不利,长安岌岌可危。困守孤城的高适向监军太监回忆起自己与李白的一生往事。",
				"filmType": {
					"name": "4D",
					"value": 13
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1688774400,
				"timeType": 3,
				"runtime": 168,
				"grade": "7.9",
				"item": {
					"name": "4D",
					"type": 13
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6483,
				"name": "念念相忘",
				"poster": "https://pic.maizuo.com/usr/movie/e36096f473478b77cba07cfda4744877.jpg",
				"actors": [
					{
						"name": "刘雨霖",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/214f1e41e10cec9306ce446e7e58e818.jpg"
					},
					{
						"name": "刘浩存",
						"role": "许念念",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/87ec0d6cf387eea9bf0a4346bf85fbc7.jpg"
					},
					{
						"name": "宋威龙",
						"role": "杨燚 / 杨四火",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/5a75ba7a42eef50b96a6105a8276a71a.jpg"
					},
					{
						"name": "卜冠今",
						"role": "向语安",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/632ba29c86ce3a0763a637f087d82db3.jpg"
					},
					{
						"name": "郭丞",
						"role": "路望",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/1e70a18a58ac2a9a0ae3f9161531c667.jpg"
					}
				],
				"director": "刘雨霖",
				"category": "青春|爱情",
				"synopsis": "你是否也有一个念念不忘的人?2023七夕,想念不如相见。转校生许念念与少年杨燚因误会结下梁子,水火不容的两人展开一系列比拼,本以为是好胜心作祟,却在不知不觉中萌发了情愫。飒爽的少女与中二的少年,就这样一起度过了热血又难忘的高中时光,最后却遗憾地擦身而过……当念念不忘的两人再次相见,他们能否勇敢一场,排除万难直面内心的喜欢?",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1692662400,
				"timeType": 3,
				"runtime": 108,
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			},
			{
				"filmId": 6405,
				"name": "八角笼中",
				"poster": "https://pic.maizuo.com/usr/movie/b6be063ea8bb7d4ecd09299b800fe510.jpg",
				"actors": [
					{
						"name": "王宝强",
						"role": "导演",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/d4b78d7453835395d39c47e418ede467.jpg"
					},
					{
						"name": "王宝强",
						"role": "向腾辉",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/d4b78d7453835395d39c47e418ede467.jpg"
					},
					{
						"name": "陈永胜",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/eec17eff886074b1b48e3646058178a4.jpg"
					},
					{
						"name": "史彭元",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/829baff38ad218ff169cd188f0d895a7.png"
					},
					{
						"name": "王迅",
						"role": "演员",
						"avatarAddress": "https://pic.maizuo.com/usr/movie/e6d3df29a73643f18e142ffcf029a8bd.jpg"
					}
				],
				"director": "王宝强",
				"category": "剧情",
				"synopsis": "暑期劲燃现实题材佳作!根据真实事件改编,王宝强六年打磨,动情演绎震撼人心!电影讲述了向腾辉(王宝强 饰)倾注心血想把当地无人照料的孩子培养成才,这让生活本没有出路的孩子们看到了一丝通向未来的曙光。然而,随着往日的表演视频被爆出,这些“残忍、血腥”的画面刺激了不明真相的人们的神经。一夜之间,舆论开始发酵。向腾辉的生活、孩子们的前途都陷入到人们以善良为名编织的大网中,让他们难以挣脱,重回泥沼,关于未来,他们的“出路”又将在哪……",
				"filmType": {
					"name": "2D",
					"value": 1
				},
				"nation": "中国大陆",
				"language": "",
				"videoId": "",
				"premiereAt": 1688601600,
				"timeType": 3,
				"runtime": 117,
				"grade": "7.5",
				"item": {
					"name": "2D",
					"type": 1
				},
				"isPresale": true,
				"isSale": false
			}
]

此文件放在public目录下

 

非父子组件通信---完整代码:

import React, { Component } from 'react'
import anxios from 'axios'
import FilmItem from './compoent/FilmItem';
import FileDetail from './compoent/FileDetail';

export default class App extends Component {

    constructor(){
        super();

        this.state = {
            cinemaList: [],
            info:''
            
        }
        anxios.get(`film.json`).then(res=>{
            console.log(res);
            this.setState({
                cinemaList:res.data
            })
        })

       
    }



    render() {
        return (
            <div>
                {this.state.cinemaList.map((item)=>
                    <FilmItem key={item.filmId} {...item} onEvent={(info)=>{
                        this.setState({
                            info:info
                        })
                    }}/>)
                
                }

                <FileDetail value={this.state.info}></FileDetail>
                
                
            </div>
        )
    }
}


import React, { Component } from 'react'
import '../css/film.css'

export default class FilmItem extends Component {

    

    render() {
        let {name,poster,grade,synopsis}=this.props
        return (
            <div className='filmInfo' onClick={()=>{
                this.props.onEvent(synopsis);
            }}>
                <img src={poster} alt={name}></img>
                <h4>{name}</h4>
                <div>观众评分:{grade}</div>
            </div>
        )
    }
}

import React, { Component } from 'react'
import '../css/film.css'
export default class FileDetail extends Component {

    render() {
        let {value}=this.props
        return (
            <div className='fileDetail'>
                <h4>电影介绍</h4>
                <div>{value}</div>
            </div>
        )
    }
}

.filmInfo img{
    float: left;
    width: 100px;
    height: 150px;
}


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

.fileDetail{
    position: fixed;
    right: 0;
    top: 100px;
    background-color: aquamarine;
    border: 1px solid red;
    width: 500px;

}

5.2 发布订阅模式

代码如下:

一个public.js

export  var bus={

    list:[],

    subscrible(callback){//订阅
        bus.list.push(callback);
    },

    publish(text){//发布
        //遍历所有的list  将回调函数执行
        this.list.forEach(callback=>{
            callback && callback(text)
        });
    }



}

此js中有一个对象  ,对象中有一个数组,订阅方法,发布方法。

订阅方法中传入一个回调函数,然后将回调函数加入到数组中。

发布方法中传入一个值,然后遍历数组,执行数组中的回调函数,并给回调函数传入一个值

import React, { Component } from 'react'
import anxios from 'axios'
import FilmItem from './compoent/FilmItem';
import FileDetail from './compoent/FileDetail';
import './00_public'

export default class App extends Component {

    constructor(){
        super();

        this.state = {
            cinemaList: [],
            info:''
            
        }
        anxios.get(`film.json`).then(res=>{
            console.log(res);
            this.setState({
                cinemaList:res.data
            })
        })

       
    }



    // render() {
    //     return (
    //         <div>
    //             {this.state.cinemaList.map((item)=>
    //                 <FilmItem key={item.filmId} {...item} onEvent={(info)=>{
    //                     this.setState({
    //                         info:info
    //                     })
    //                 }}/>)
                
    //             }

    //             <FileDetail value={this.state.info}></FileDetail>
                
                
    //         </div>
    //     )
    // }



    render() {
        return (
            <div>
                {this.state.cinemaList.map((item)=>
                    <FilmItem key={item.filmId} {...item} />)
                
                }

                <FileDetail ></FileDetail>
                
                
            </div>
        )
    }
}


import React, { Component } from 'react'
import '../css/film.css'
import {bus} from '../00_public'
export default class FilmItem extends Component {//发布者



    // render() {
    //     let {name,poster,grade,synopsis}=this.props
    //     return (
    //         <div className='filmInfo' onClick={()=>{
    //             this.props.onEvent(synopsis);
    //         }}>
    //             <img src={poster} alt={name}></img>
    //             <h4>{name}</h4>
    //             <div>观众评分:{grade}</div>
    //         </div>
    //     )
    // }


    render() {
        let { name, poster, grade, synopsis } = this.props
        return (
            <div className='filmInfo' onClick={() => {
                bus.publish(synopsis)  //一点击就调用发布方法
            }}>
                <img src={poster} alt={name}></img>
                <h4>{name}</h4>
                <div>观众评分:{grade}</div>
            </div>
        )
    }
}

import React, { Component } from 'react'
import '../css/film.css'
import {bus} from '../00_public'

export default class FileDetail extends Component {  //订阅者

    // render() {
    //     let {value}=this.props
    //     return (
    //         <div className='fileDetail'>
    //             <h4>电影介绍</h4>
    //             <div>{value}</div>
    //         </div>
    //     )
    // }


    constructor(){
        super();
        this.state={
            info:''
        }
        bus.subscrible((value)=>{
            this.setState({
                info:value
            })
        });
    }

    render() {

        return (
            <div className='fileDetail'>
                <h4>电影介绍</h4>
                <div>{this.state.info}</div>
            </div>
        )
    }
}

过程是这样的:

FileDetail组件中有一个构造函数,FileDetail组件一生成,就会执行构造函数中的订阅方法,订阅方法传入一个回调函数,回调函数接受一个值。并将值设置到状态里。

FilmItem组件有一个点击事件,一点击就会调用publish方法,并传入一个值,然后根据public.js中所写的此方法的逻辑,会调用此前传入的回调函数。这样就通了

 

 点击左边,右边方框就会改变内容

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java-请多指教

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值