【问题标题】:MapStateToProps and MapDispachToProps in parent and child components not working父组件和子组件中的 MapStateToProps 和 MapDispachToProps 不起作用
【发布时间】:2020-06-29 14:46:44
【问题描述】:

在我的 app.js 中,我有我的 mapDispachToProps 函数,它应该向 redux 商店中的 reducer 发送一个 type:increment 的动作。当 reducer 收到它时,他应该将初始状态增加 1。

在标题组件中,它是 app.js 组件的子组件,我想通过 mapStateToProps 和 this.props.value 显示新值。问题是它不起作用,我在控制台中没有收到错误消息。

当我在 App.js 中执行所有操作时,它运行良好。

我做错了什么?

提前致谢

我的 index.js

let store = createStore(increaseReducer);

ReactDOM.render(
  <Provider store = {store}>
    <App/>
  </Provider>,
  document.getElementById('root')
);

我的店铺

export function increaseReducer(state = 0, action) {
    if(action.type == "INCREMENT") {
        return state+1;
    }   

    else {
        return state;
    }
}
export default increaseReducer;

我的 app.js

import React, {Component} from 'react';
import{ connect }from 'react-redux';
import {Heading} from './components/heading';

class App extends Component {
  constructor(props) {
    super(props);
  }
  render() {
  return (
    <div className="App">
       <Heading></Heading>
       <button onClick={this.props.increment} > Counter</button>
    </div>
  );
  }
}

let mapDispachToProps= {
  increment:()=> {
  return {type:"INCREMENT"}}
}

let AppContainer= connect(null,mapDispachToProps)(App);
export default AppContainer;

我的heading.js

import React, {Component} from 'react';
import{ connect }from 'react-redux';

export class Heading extends Component {
        constructor(props){
            super(props);
        }

        render() {
            return(
                    <h1>Click Counter: {this.props.value}  </h1>    
                )
        }
}

let mapStateToProps = (state)=>{return {
  value: state
}}

let headingContainer = connect(mapStateToProps)(Heading);

export default headingContainer;

【问题讨论】:

  • 您需要调度您的操作
  • @demkovych 不,mapDispatchToProps 可以是 object,mapDispatchToProps 没有问题(除了魔术字符串而不是常量)。
  • 如果你把他们派到某个地方没有错,但问题是他不使用动作。
  • @demkovych 是的,他这样做了:&lt;button onClick={this.props.increment} &gt; 我将代码复制到我的答案中的 sn-p 并且它有效。调度不是问题,但导入才是问题。

标签: reactjs redux react-redux


【解决方案1】:

标题导出默认,所以在 App 中应该是:

import Heading from './components/heading';

这是您作为 sn-p 的代码,它可以工作:

const {
  Provider,
  connect,
} = ReactRedux;
const { createStore } = Redux;
const { Component } = React;

function increaseReducer(state = 0, action) {
  if (action.type == 'INCREMENT') {
    return state + 1;
  } else {
    return state;
  }
}
let store = createStore(increaseReducer);

//heading
class HeadingComponent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <h1>Click Counter: {this.props.value} </h1>;
  }
}

let mapStateToProps = (state) => {
  return {
    value: state,
  };
};

let Heading = connect(mapStateToProps)(HeadingComponent);

class App extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div className="App">
        <Heading></Heading>
        <button onClick={this.props.increment}>
          {' '}
          Counter
        </button>
      </div>
    );
  }
}

let mapDispachToProps = {
  increment: () => {
    return { type: 'INCREMENT' };
  },
};

let AppContainer = connect(null, mapDispachToProps)(App);

ReactDOM.render(
  <Provider store={store}>
    <AppContainer />
  </Provider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>


<div id="root"></div>

【讨论】:

    【解决方案2】:

    您需要调度您的操作:

    
    const mapDispachToProps = dispatch => {
      return {
        increment: () => dispatch({
          type:"INCREMENT"
        }}
      }
    }
    

    减速器:

    export default (state = 0, action) => {
        switch (action.type) {
          case 'INCREMENT':
            return state + 1;
          default:
            return state;
        }
    

    【讨论】:

    • 感谢您的帮助,问题还在于调度标题子项不显示初始值 0
    • 这个开关与 OP 的 if/else 有什么不同?
    • 但是我如何从其他地方导入这个?为什么可以导出整个 reducer?
    • 你可以随心所欲。在我的示例中,reducer 是您的 increaseReducer 函数,但只是重写为单独的文件。你可以从任何地方得到它,比如import {increaseReducer} from 'path_to_your_reducer';
    • @FabianAndiel 这可能会有所帮助Default vs Named Export
    猜你喜欢
    • 2021-07-03
    • 2019-01-17
    • 1970-01-01
    • 2021-09-12
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 2014-09-30
    相关资源
    最近更新 更多