react之传递数据的几种方式props传值、路由传值、状态提升、redux、context

摘要:
传输数据的几种方法:1.父子值:<子值的标签={'aaa‘}索引={bbb‘}>/子标签>子值:<likey={this.props.index}>{this.props.value}</li>不仅可以传递值,还可以传递方法:parent:method={this.method}child:{this.props.method.bind(this)}

react之传递数据的几种方式

1、父子传值

父传值:<子的标签 value={'aaa'} index={'bbb'}></子的标签>
子接值:<li key={this.props.index}>{this.props.value}</li>
 
不止可以传值也可以传递方法:
父:方法={this.方法}
子:{this.props.方法.bind(this)}
react之传递数据的几种方式props传值、路由传值、状态提升、redux、context第1张
 
 
传来的参数子组件可以使用,此处用{value,index}等解构赋值省去this.props
此处的子组件利用这个deleteItem方法向父元素传递了index

react之传递数据的几种方式props传值、路由传值、状态提升、redux、context第2张

父传子,子为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

react之传递数据的几种方式props传值、路由传值、状态提升、redux、context第3张

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

react之传递数据的几种方式props传值、路由传值、状态提升、redux、context第4张

react之传递数据的几种方式props传值、路由传值、状态提升、redux、context第5张

大概项目大概如第二张图,具体应用体现在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 
 
 

免责声明:文章转载自《react之传递数据的几种方式props传值、路由传值、状态提升、redux、context》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇git使用ssh密钥和https两种认证方式汇总(转)mssql 发布库 Invalid object name 'syspublications'下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

react 配置ant时遇见的一个Error: Multiple configuration files found. Please remove one: – package.json#babel – .babelrc 解决方案

这个问题是create react app 里面的package.json里面已经配置了   "babel": {     "presets": [       "react-app"     ]   } 这样的配置,但是又在根目录下建立了一个babelrc的文件,所以导致重复,但是不可以直接删掉,不然报   编译失败 ./src/index.jsS...

不难懂--------react笔记

  在jsx中不能使用class定义类名   因为class在js中是用来定义类的  定义类名的时候用className       label中的for必须写成htmlFor         ReactDOM.render:             参数1:需要渲染的dom元素或者组件         参数2:需要将渲染好的元素挂载在哪个挂载点身上...

Object.defineProperty() 吴小明

定义:Object.defineProperty(object, propName, descriptor)为对象定义新的属性,或者对某个属性进行修改,并将这个对象返回出来 object:对象  给谁加 propName:属性名  要添加的属性的名字,是一个字符串 descriptor:属性描述  要加的这个属性有什么特点 属性描述对象的6个属性: val...

React 表格行点击事件

<Table dataSource={this.dataSources} columns={this.columns} onRow={(record) => {//表格行点击事件 return { // onClic...

08 在设备树里描述platform_device【转】

转自:https://blog.csdn.net/jklinux/article/details/78575281 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/jklinux/article/details/78575281在设备树的dts文件...

京东阅读(web)体验优化

京东有电子书可以购买,可以多端阅读。比如PC客户端,移动端,以及本文提到的PC网站端。 先换个镜头,读书要记笔记(电子版本), 方便以后查阅。 镜头换回来,但是,我们为了方便肯定是想复制,下载啊,分享啊等,但是服务商一般是不允许你这么做的。 我了,在京东买了几本书,程序相关的,为了获取好的体验,在PC网站端阅读, 发现精彩之处,想去复制到笔记里面去。 结果...