zoukankan      html  css  js  c++  java
  • react之传递数据的几种方式props传值、路由传值、状态提升、redux、context

    react之传递数据的几种方式

    1、父子传值

    父传值:<子的标签 value={'aaa'} index={'bbb'}></子的标签>
    子接值:<li key={this.props.index}>{this.props.value}</li>
     
    不止可以传值也可以传递方法:
    父:方法={this.方法}
    子:{this.props.方法.bind(this)}
     
     
    传来的参数子组件可以使用,此处用{value,index}等解构赋值省去this.props
    此处的子组件利用这个deleteItem方法向父元素传递了index

    父传子,子为styled
    父:
      <Lun pic={this.state.good ? this.state.good.image : ''}></Lun>
    子:
      const Lun = styled.div`
        100%;
        height:375px;
        background:url('${props => props.pic}') center no-repeat;
        background-size: cover;
      `
     

    2、路由传值
    import { BrowserRouter } from 'react-router-dom'
    包在最外层,我放在了我的react项目的index.js里
     
    方法一:/路径/:自己起的要传的值的名字
    父组件:
    import { Route, Switch, Redirect } from 'react-router-dom' class App extends Component { render() { return ( <Switch> <Redirect exact from="/" to="/car"></Redirect> <Route path='/home' component={Bar}/> <Route path="/shopDetail/:shopId/:shopName/:shopNote/:shopPic" component={ShopDetail} /> <Route path='/noteDetail/:noteId' component={NodeDe} /> <Route path='/goodDetail/:goodId/:shopId' component={GoodDetail} /> <Route path='/car' component={Car} /> </Switch> ); } } export default App;
             子组件: 
    <LogoCon> <div> <img src='https://ci.xiaohongshu.com/98320dbb-536e-451a-a53f-98724b56d380?imageView2/3/w/420/h/600/format/jpg/q/90' /> <div> <h2>{this.props.match.params.shopName}</h2> <h6></h6> <h5>{this.props.match.params.shopNote}篇笔记</h5> </div> <a href="javascript:void(0)">关注</a> </div> </LogoCon>

    方法二:

    var data = {id:0,name:'lili',age:16};
    
    data = JSON.stringify(data);
    
    var path = `/user/${data}`;
    
    
    
    <Link to={path}>用户</Link>
    var data = this.props.location.query;
    
    var {id,name,age} = data;

    3、状态提升:其原理是两个或者多个组件需要共享的数据放在他们公共的祖先身上,通过props实现共享

    L:父组件为<A></A>

       子组件为<B></B>

    在父组件中调用子组件:

    <A>

      <B {...props}></B>

    </A>

    以此类推。


    4、redux

    已我自己写的一个小demo为例子:

    大概项目大概如第二张图,具体应用体现在goodDetail文件夹内

    新建一个store文件夹,做一个数据处理的汇总

    store/redecers.js
    store/redecers.js
    
    import { combineReducers } from 'redux'
    
    import shop from 'pages/shop/reducer'
    import car from 'pages/goodDetail/reducer'
    
    export default combineReducers({
        shop,
        car
    })

      store/index.js

    import { createStore, applyMiddleware } from 'redux'
    
    import thunk from 'redux-thunk'
    
    import reducers from './reducers'
    
    const store = createStore(reducers, applyMiddleware(thunk))
    
    export default store

      goodDetail/actionType.js

    export const GET_CAR_DATA = 'car/get_car_data'

      goodDetail/actionCreator.js

    import { GET_CAR_DATA } from './actionType'
    
    export const loadCarDataSync = (goods) => {
        //console.log(goods)
        return {
          type: GET_CAR_DATA,
          goods:goods
        }
      }
      
      export const loadCarDataAsync = (dispatch,obj) => {
        // console.log(1)
        //console.log(obj)
        return () => {
            dispatch(loadCarDataSync(obj))
        }
      }

      goodDetail/reducer.js(处理数据)

    import {GET_CAR_DATA} from './actionType'
    
    const defaultState = {
        goods:[{
          shopName: "豌豆公主海外美妆集合店",
          he:[
            { image: "https://img.xiaohongshu.com/items/4d9747c4f9c03b7c2eafc4d066061968@_320w_320h_1e_1c_0i_90Q_1x_2o.jpg",
              introduce: "clé de Peau Beauté肌肤之钥 沁肌紧肤水磨精华液 170ml",
              kuSave: 296161,
              num: 4,
              price: 609
            }
          ]
        }
      ]
    }
    
    export default (state=defaultState, action) => {
        if (action.type === GET_CAR_DATA) {
          if(!!state.goods){
            const obj = state.goods.find(v => v.shopName === action.goods.shopName )
            if(!!obj){
              const same = obj.he.find(i => i.introduce === action.goods.he[0].introduce )
              console.log(obj)
              if(!!same){
                same.num++;
              }else{
                obj.he.push(...action.goods.he)
              }
              return {
                goods: [...state.goods]
              }
            }else{
              return {
                goods: [...state.goods,action.goods]
              }
            }
          }
          else{
            return {
              goods: [action.goods]
            }
          }
        }
    
        return state
    }  

    整个项目最外面的index.html中引入

    import store from './store'
     
    在goodDetail/goodDetai.js中
    import { connect } from 'react-redux'
    
    import {
        Link,
        withRouter
    } from 'react-router-dom'
    
    
    import { loadCarDataAsync } from './actionCreator'
    
    
    const mapState = (state) => {
        //console.log(state)
        return {
          goods: state.car.goods
        }
    }
    
    const mapDispatch = (dispatch) => {
        return {
            loadCategories (obj) {
                //console.log(obj)
                dispatch(loadCarDataAsync(dispatch,obj))
            }
        }
    }
    
    
    
    
    中间代码省略,在你需要的地方调用
              this.props.loadCategories(
                    {
                        shopName:this.state.good.vendor_name,
                        he:[{
                            image:this.state.good.image,
                            introduce:this.state.good.desc,
                            price:this.state.good.discount_price,
                            kuSave:this.state.good.fav_info.fav_count,
                            num:Number(this.refs.goodNum.value)
                        }]
                    }
                )    (参数可传可不传,不传的话,其余对应的地方记得修改)
    
    
    
    export default withRouter(connect(mapState, mapDispatch)(GoodDetail))

    5、context

    不合适修改数据
    更适合共享数据
     
    getChildContext()
     
    祖先组件:
      1>import PropsTypes from 'prop-types'
      2>static childCOntextTypes={
        XX:PropsTypes.string
       }
      3>getChildContext(){
        return {XX:xx}
       }
      4>引入一个子组件
     
     
    子组件接收:
      this.context.XX
     
     
     

     
    新版写法:
    import React from 'react'
    
    const ThemeContext = React.createContext('green');
    
    class App extends React.Component {
      render() {
        return (
    
        //    此处相当于注入,会覆盖掉green,value只能写value
        //   <ThemeContext.Provider value="pink">
        //     <Toolbar />
        //   </ThemeContext.Provider>
    
    
        //    这种写法相当于一个函数调用,此处的background可以起别的名字
        <ThemeContext.Consumer background={this.context}>
            {context => (
              <Toolbar />
            )}
        </ThemeContext.Consumer>
    
        );
      }
    }
    
    function Toolbar(props) {
      return (
        <div>
          <ThemedButton />
        </div>
      );
    }
    
    class ThemedButton extends React.Component {
      static contextType = ThemeContext;
      render() {
        return <div style={{background:this.context}} >111</div>;
      }
    }
    
    
    
      export default App 
     
     

  • 相关阅读:
    e807. 设置进程监听对话框的延迟弹出
    e806. 创建进程监听对话框
    Spring MVC静态资源处理
    SpringMVC处理方法的数据绑定
    HttpMessageConverter
    Redis中对Key进行分类
    LinkedHashMap源码剖析
    TreeMap源代码深入剖析
    CMS垃圾收集器
    @Java VisualVM 插件地址
  • 原文地址:https://www.cnblogs.com/yangyangxxb/p/10035834.html
Copyright © 2011-2022 走看看