1. 程式人生 > >react之傳遞資料的幾種方式props傳值、路由傳值、狀態提升、redux、context

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`     width: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/[email protected]_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