React基础二

一,父子通信

通信方法
1.父传子是通过属性 , 子传父是通过方法,回调函数
子传父

import React, { Component } from 'react'
class App extends Component {
    render() {
        return <div>1
            <Child onMyEvent={() => {
                console.log('defined by app')
            }}></Child>
        </div>
    }
}
class Child extends Component {
    state = {
        childname: 'childname-111111'
    }
    render() {
        console.log(this.props.onMyEvent)
        return <div>child
            <button onClick={() => {
                this.props.onMyEvent()
            }}>子传父</button>
        </div>
    }
}
export default App

案例,在Navbar中点击按钮,控制Sidebar隐藏显示,通过回调函数调用onEvent事件。

import React, { Component } from 'react'
class App extends Component {
    state = {
        isShow: false
    }
    render() {
        return <div>app
            <Navbar onEvent={this.handleClick}></Navbar>
            {
                this.state.isShow ? <Sidebar></Sidebar> : null
            }
            {/* <Sidebar></Sidebar> */}
        </div >
    }
    handleClick = () => {
        this.setState({
            isShow: !this.state.isShow
        })
    }
}

var Navbar = ({ onEvent }) => {
    console.log(onEvent)
    return <div>
        navbar
        <button onClick={() => {
            onEvent()
        }}> click</button >
    </div>
}
var Sidebar = () => {
    return <div>
        Sidebar
    </div>
}

export default App

var Navbar = ({ onEvent }) => {
    console.log(onEvent)
    return <div>
        navbar
        <button onClick={() => {
            onEvent()
        }}> click</button >
    </div>
}

//可以改写成 

var Navbar = ({ onEvent }) => <div>
    Navbar
    <button onClick={onEvent}></button>
</div>

2.ref标记,父组件拿到子组件的引用,从而调用子组件的方法
在父组件中清除子组件的input输入框的value值(了解即可,不提倡)

 render() {
     return <div>
         App
         <Child ref="mychild"></Child>
         <button onClick={() => {
             this.refs.mychild.mymethod('app')
         }}>click</button>
     </div>
 }

二,非父子通信

1.状态提升(中间人模式)
2.发布订阅模式
3.context状态树传参

import React, { Component } from 'react'
const Store = {
    list: [],
    subscribe(callback) {
        this.list.push(callback)
    },
    publish(data) {
        for (var i in this.list) {
            this.list[i](data)
        }
    }
}
class App extends Component {

    render() {
        return <div>
            App
            <Child1></Child1>
            <Child2></Child2>
        </div>
    }
}
class Child1 extends Component {
    render() {
        return <div>
            Child1  ----  发布者
            <button onClick={() => {
                console.log('发布')
                Store.publish('child1发布')
            }}>发布</button>
        </div>
    }
}

class Child2 extends Component {
    componentDidMount() {
        console.log('ajax,监听事件')
        Store.subscribe(this.mycallback)
    }
    mycallback(data) {
        console.log('订阅者:我订阅到啦~~~~~', data)
    }
    render() {
        return <div>
            Child2  ----  订阅者
            <button onClick={() => {
                console.log('订阅')
            }}>订阅</button>
            <Child2A></Child2A>
        </div>
    }
}
class Child2A extends Component {
    componentDidMount() {
        console.log('ajax,监听事件')
        Store.subscribe(this.mycallback)
    }
    mycallback(data) {
        console.log('订阅者2A(订阅者2的孩子):我订阅到啦~~~~~', data)
    }
    render() {
        return <div>
            Child2A ---  Child2 的孩子

        </div>
    }
}
export default App

context

import React, { Component } from 'react'
const GlobalContext = React.createContext()
class App extends Component {
    state = {
        number: 100
    }
    render() {
        return <GlobalContext.Provider value={
            {
                call: '打电话',
                sms: '短信服务' + this.state.number,
                changesms: () => {
                    console.log('change sms')
                    this.setState({
                        number: 20000
                    })
                }
            }
        }>
            <div>
                App
                <Child1></Child1>
                <Child2></Child2>
            </div>
        </GlobalContext.Provider>
    }
}
class Child1 extends Component {
    render() {
        return <GlobalContext.Consumer>
            {
                (context) => <div>child1-- {context.call}
                    <button onClick={() => {
                        context.changesms()
                    }}>click</button>
                </div>
            }

        </GlobalContext.Consumer>
    }
}
export default App

三,插槽

{this.props.children}

import React, { Component } from 'react'
import Swiper from 'swiper'
import "swiper/swiper-bundle.min.css"

class App extends Component {
    state = {
        datalist: []
    }
    render() {
        return <div>app
            <button onClick={() => {
                this.setState({
                    datalist: ['111', '222', '333']
                })
            }}>click</button>
            <SwiperA key={this.state.datalist.length}>
                {this.state.datalist.map(item =>
                    <div class="swiper-slide" key={item}>{item}</div>
                )}
            </SwiperA>
        </div>
    }
}

class SwiperA extends Component {
    render() {
        return <div className="swiper-container">
            <div className="swiper-wrapper">
                {this.props.children}
            </div>
        </div>
    }
    componentDidMount() {
        new Swiper(".swiper-container")
    }
}
export default App

四,动态组件

import React, { Component } from 'react'
export default class App extends Component {
    state = {
        current: Home
    }
    render() {
        return <div>
            <ul>
                <li onClick={() => this.handleClick(Home)}>home</li>
                <li onClick={() => this.handleClick(List)}>list</li>
                <li onClick={() => this.handleClick(Shopcar)}>shopcar</li>
            </ul>
            <Dcomponent component={this.state.current}></Dcomponent>
        </div>
    }
    handleClick(data) {
        this.setState({
            current: data
        })
    }
}

class Dcomponent extends Component {
    render() {
        console.log(this.props.component)//组件
        var MyComponent = this.props.component
        return <div>
            <MyComponent></MyComponent>
        </div>
    }
}

function Home() {
    return <div>home</div>
}

function List() {
    return <div>List</div>
}

function Shopcar() {
    return <div>Shopcar</div>
}

五,路由

路由是根据不同的url地址展示不同的内容或页面

cnpm install react-router-dom

1.声明式导航,重定向

route.js

import React, { Component } from 'react'
import { HashRouter, Route, Redirect, Switch } from 'react-router-dom'
import App from '../App'
import Film from '../Views/Film/Film'
import Center from '../Views/Center/Center'
import Cinema from '../Views/Cinema/Cinema'

const router = <HashRouter>
    <App>
        <switch>
            <Route path="/film" component={Film}></Route>
            <Route path="/center" component={Center}></Route>
            <Route path="/cinema" component={Cinema}></Route>
            <Redirect from="/" to="/film" exact></Redirect>
            <Redirect to="/error"></Redirect>
        </switch>
    </App>
</HashRouter>

export default router

Tabbar.js
NavLink

import React, { Component } from 'react'
import { Link, NavLink } from 'react-router-dom'
import './tabbar.css'
export default class Tabbar extends Component {
    render() {
        return (
            <nav>
                <ul>
                    <li><NavLink to="/film" activeClassName="active">电影</NavLink></li>
                    <li><NavLink to="/cinema" activeClassName="active">影院</NavLink></li>
                    <li><NavLink to="/center" activeClassName="active">个人中心</NavLink></li>
                </ul>
            </nav>
        )
    }
}

2.嵌套路由

Film.js中留好插槽 {this.props.children}
route.js

<App>
    <Switch>
        <Route path="/film" render={() =>
            <Film>
                <Switch>
                    <Route path="/film/commingSoon" component={CommingSoon}></Route>
                    <Route path="/film/nowPlaying" component={NowPlaying}></Route>
                    <Redirect from="/film" to="/film/commingSoon"></Redirect>
                </Switch>
            </Film>}
        ></Route>
        <Route path="/center" component={Center}></Route>
        <Route path="/cinema" component={Cinema}></Route>
        <Redirect from="/" to="/film" exact></Redirect>
        <Redirect to="/error"></Redirect>
    </Switch>
</App>

3.动态路由

componentDidMount(){
    console.log(this.props.match.params.myid)
}
handleClick = (id) => {
    console.log(this.props)
    this.props.history.push(`/detail/${id}`)
}

4.路由拦截

<Route path="/center" render={() =>
   localStorage.getItem('token') ? <Center></Center> : <Redirect to="/login"></Redirect>
}></Route>

5.withRouter 高阶函数,高阶组件

HOC— High Order Component高阶组件

import React, { Component } from 'react'
import { withRouter } from 'react-router'
class FilmItem extends Component {

    render() {
        let { item } = this.props
        return (
            <div>
                <li onClick={() => this.handleClick(item)}>film item---  {item}</li>
                <WrapChild><Child> </Child></WrapChild>
            </div>
        )
    }
    handleClick = (id) => {
        console.log(11)
        this.props.history.push(`/detail/${id}`)
    }
}

export default withRouter(FilmItem)

var Child = (props) => <div>child --{props.name}</div>

var WrapChild = withShirley(Child)

function withShirley(MyComponent) {
    return class WithShirleyComponent extends Component {
        render() {
            return <div>
                我是包装组件,传进来的组件 , 成为我的孩子组件
                <MyComponent name="111"></MyComponent>
            </div>
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值