简体   繁体   English

React Redux存储将道具传递给孩子的问题

[英]Problems with React Redux store passing props to children

What I am trying to accomplish is to have one "controller" file that renders out all the components to my page.. And I tried implementing redux to pass props to my component childrens but I do not get it to work. 我要完成的工作是拥有一个“控制器”文件,该文件将所有组件呈现到我的页面上。我尝试实现redux来将prop传递给我的子组件,但我无法使其工作。 Here's my files: 这是我的文件:

index.jsx index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'
import store from './js/store.jsx'
import App from './js/App.jsx'

// Assigning the sections
const nav = document.getElementsByClassName('cart')[0];

//Render the components
ReactDOM.render(<Provider store={store}>
<App />

</Provider>, nav) 

App.jsx App.jsx

import React from 'react'
import Cart from './components/cart/Cart.jsx'

export default class App extends React.Component {
  constructor(props) {
        super(props);
    }

  render() {
    return <Cart />
  }
}

Cart.jsx Cart.jsx

import React from 'react'
import { connect } from 'react-redux'
import {fetchCart} from '../../actions/cartActions'
var ReactDOM = require('react-dom');


@connect((store) => {

})
export default class Cart extends React.Component {
    componentWillMount() {
        this.props.dispatch(fetchCart())
    }
    constructor(props) {
        super(props);
         this.state = {

        };

    }

  render() {
    return( <div>

    <div className="cart-scroll-area">
          {/* Bryt ut till egna komponenter */}
          <header className="cart-header"></header>
          <header className="cart-meta">
            <div className="cart-meta-info">
                <div className="cart-timer">Avsluta din order inom<br /><strong>xxxx</strong><br /></div>
                <div className="status ok">
                    för leverans tidigast xxxx
                </div>
            </div>
          </header>
          <section className="cart-section cart-errors"></section>
          <section className="cart-section cart-section-homelist"></section>
          <section className="cart-section cart-section-bag-header"></section>
          <section className="cart-section cart-section-prenumeration"></section>
          <section className="cart-section cart-section-flexbag"></section>
          <section className="cart-section cart-section-recipes"></section>
          <section className="cart-section cart-section-mostbought"></section>
          <section className="cart-section cart-section-accessories"></section>
      </div>
      <div className="cart-scroll-footer">
          <div className="cart-total"></div>
          <div className="cart-total-price"></div>
          <footer className="cart-footer"></footer>
      </div>
      </div>
    )
  }
}

¨ ¨

cartActions.js cartActions.js

let restPath = "/ShoppingCart";

export function fetchCart(){
  return {
    type: "FETCH_CART",
    payload: {data:["Event 1", "Event 2"]}
    //payload: axios.get("http://localhost:3000/api/v1/events")
  }
}

cartReducer.js cartReducer.js

const initialState = {
  fetching: false,
  fetched: false,
  cart: [],
  error: null
}

export default function reducer(state=initialState, action=null) {
console.log(action.payload)
  switch (action.type){

    case "FETCH_CART_PENDING" : {
      return {...state, fetching:true}
      break;
    }
    case "FETCH_CART_REJECTED" : {
      return {...state, fetching:false, error:action.payload}
      break;
    }
    case "FETCH_CART_FULFILLED" : {
      return {...state,
        fetching:false,
        fetched:true,
        cart:action.payload.data
      }
      break;
    }
    case "FETCH_CART" : {
      return {...state,
        fetching:false,
        fetched:true,
        cart:action.payload.data
      }
      break;
    }
  }
  return state
}

And finally here's my store.jsx 最后是我的store.jsx

import {applyMiddleware, createStore} from 'redux'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
import promise from 'redux-promise-middleware'
import reducer from './reducers'

const middleware = applyMiddleware(promise(), thunk, logger())

export default createStore(reducer, middleware)

Right now I am getting this.props.dispatch is not a function. 现在我得到this.props.dispatch不是一个函数。 And I do not get any props/store containing the "payload: {data:["Event 1", "Event 2"]}" 而且我没有任何包含"payload: {data:["Event 1", "Event 2"]}"道具/商店

Can anyone help me out? 谁能帮我吗? :( :(

You are missing some key parts when it comes to connecting your app to redux. 在将应用程序连接到Redux时,您缺少一些关键部分。 You need to connect redux to the react container you wish to have access to the data. 您需要将redux连接到希望访问数据的react容器。 You also need to create a function to mapStateToProps , which allows you access the data in the redux store as props. 您还需要为mapStateToProps创建一个函数,该函数允许您以道具的形式访问redux存储中的数据。 You also will need to create a function called mapDispatchToProps to allow you use the fetchCart method in your container. 您还需要创建一个名为mapDispatchToProps的函数,以允许您在容器中使用fetchCart方法。

Firstly, you need to import connect from react-redux . 首先,您需要从react-redux导入connect

import {Provider, connect} from 'react-redux'

To connect the App component to redux you need to use the redux connect method and pass in the two functions you created called mapStateToProps , mapDispatchToProps and the App component as callbacks. 要将App组件连接到redux您需要使用redux connect方法并传入创建的两个函数mapStateToPropsmapDispatchToPropsApp组件作为回调。

const ConnectedApp = connect(mapStateToProps, mapDispatchToProps)(App);

You then put the ConnectedApp inside the Provider in the ReactDOM.render function. 然后,将ConnectedApp放在ReactDOM.render函数的Provider内部。

ReactDOM.render(
<Provider store={store}>
    <ConnectedApp />
</Provider>, nav) 

import {Provider, connect} from 'react-redux'    

 const mapStateToProps = state => ({
    state: state
 })

const mapDispatchToProps = dispatch => ({fetchCart: () => dispatch(fetchCart())})

const nav = document.getElementsByClassName('cart')[0];
const ConnectedApp = connect(mapStateToProps, mapDispatchToProps)(App);

//Render the components
ReactDOM.render(
<Provider store={store}>
    <ConnectedApp />
</Provider>, nav) 

To use the redux-logger you need to do the following 要使用redux-logger您需要执行以下操作

import createLogger from 'redux-logger';
const logger = createLogger();
const middleware = applyMiddleware(thunk, promise, logger);

Please note the order in which you pass in logger matters. 请注意您传递logger事项的顺序。 It needs to be passed into applyMiddleware as the final argument. 它需要作为最后一个参数传递到applyMiddleware中。

You're usage of connect is incorrect. 您使用的connect不正确。 You want to map the state and dispatcher to props for the component. 您想要将状态和调度程序映射到组件的prop。 In addition, I would suggest connecting the top-level App container and passing props to its children. 另外,我建议连接顶级App容器并将props传递给其子级。 Try something like this : 尝试这样的事情:

App.jsx App.jsx

import React from 'react'
import Cart from './components/cart/Cart.jsx'
import {connect} from 'react-redux'
import {fetchCart} from '../../actions/cartActions'

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <Cart
     fetching={this.props.fetching}
     fetched={this.props.fetched}
     cart={this.props.cart}
     error={this.props.error}
     fetchCart={this.props.fetchCart} />
  }
}

const mapStateToProps = (state) => {
  // These will be passed as props into the component.
  return { 
    fetching: state.fetching,
    fetched: state.fetched,
    cart: state.cart,
    error: state.error
  };
};

const mapDispatchToProps = (dispatch) => {
  // These will be passed as props into the component.
  return {
    fetchCart: () => dispatch(fetchCart()) 
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

Cart.jsx Cart.jsx

import React from 'react'
import ReactDOM from 'react-dom';

export default class Cart extends React.Component {
  componentWillMount() {
    this.props.fetchCart();
  }

  constructor(props) {
    super(props);
    this.state = { };
  }

  render() {
    // this.props.fetching, this.props.fetched etc. should exist.
    console.log(this.props);

    return(
     <div>
        <div className="cart-scroll-area">
           {/* Bryt ut till egna komponenter */}
           <header className="cart-header"></header>
           <header className="cart-meta">
              <div className="cart-meta-info">
                 <div className="cart-timer">Avsluta din order inom<br /><strong>xxxx</strong><br /></div>
                 <div className="status ok">
                    för leverans tidigast xxxx
                 </div>
              </div>
           </header>
           <section className="cart-section cart-errors"></section>
           <section className="cart-section cart-section-homelist"></section>
           <section className="cart-section cart-section-bag-header"></section>
           <section className="cart-section cart-section-prenumeration"></section>
           <section className="cart-section cart-section-flexbag"></section>
           <section className="cart-section cart-section-recipes"></section>
           <section className="cart-section cart-section-mostbought"></section>
           <section className="cart-section cart-section-accessories"></section>
        </div>
        <div className="cart-scroll-footer">
           <div className="cart-total"></div>
           <div className="cart-total-price"></div>
           <footer className="cart-footer"></footer>
        </div>
     </div>
    )
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM