【问题标题】:Importing React component with Redux methods使用 Redux 方法导入 React 组件
【发布时间】:2018-04-10 10:35:49
【问题描述】:

我整理了一个简单的组件来尝试理解一些 React 和 Redux 概念。

我现在正试图将 Redux 逻辑分离成一个单独的组件,这样总共就有两个组件。

当我尝试编译时,NewComponent 中的所有方法/对象都未定义。当我使用 this 添加上下文时,我得到了同样的错误。

下面是我在尝试将 Redux 方法/对象放入单独组件之前的原始组件(工作正常)。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { createStore, combineReducers } from 'redux'
import { Provider, connect } from 'react-redux'


const incrementAction = {
  type: 'INCREMENT',
  value: 1
}

const decrementAction = {
  type: 'DECREMENT',
  value: 1
}

function reducer(state = 0, action) {
  if (action.type === 'INCREMENT') {
    return state + 1
  } else if (action.type === 'DECREMENT'){
    return state - 1
  } else {
    return state
  }
}

// Map Redux state to component props
function mapStateToProps(state) {
  return {
    value: state
  }
}

// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
  return {
    onIncrementClick: () => dispatch(incrementAction),
    onDecrementClick: () => dispatch(decrementAction)
  }
}


const store = createStore(reducer)



class View extends Component {

  showState() {
      console.log(store.getState())
  }


  render() {

    const { value, onIncrementClick, onDecrementClick } = this.props

    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title"></h1>
        </header>

      <h2>Counter</h2>

      <div onClick = {onIncrementClick}> <p className="button"> + </p></div>
      <div onClick = {onDecrementClick}> <p className="button"> - </p></div>
      <div onClick = {this.showState}> <p className="button"> Show State </p></div>

    </div>
    );
  }
}

View = connect(
  mapStateToProps,
  mapDispatchToProps
)(View)


const WrappedApp = () => (
  <Provider store={store}>
    <View />
  </Provider>
);

export default WrappedApp;

编辑

这是我尝试分解上述内容后的组件。

NewComponent:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { createStore, combineReducers } from 'redux'
import { Provider, connect } from 'react-redux'


class NewComponent extends Component {

  constructor(props){
    super(props)

    const incrementAction = {
      type: 'INCREMENT',
      value: 1
    }

    const decrementAction = {
      type: 'DECREMENT',
      value: 1
    }

    const store = createStore(reducer)

  }



  reducer(state = 0, action) {
    if (action.type === 'INCREMENT') {
      return state + 1
    } else if (action.type === 'DECREMENT'){
      return state - 1
    } else {
      return state
    }
  }

  // Map Redux state to component props
  mapStateToProps(state) {
    return {
      value: state
    }
  }

  // Map Redux actions to component props
  mapDispatchToProps(dispatch) {
    return {
      onIncrementClick: () => dispatch(incrementAction),
      onDecrementClick: () => dispatch(decrementAction)
    }
  }

}


export default NewComponent;

还有View:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { createStore, combineReducers } from 'redux'
import { Provider, connect } from 'react-redux'
import NewComponent from './NewComponent'


class View extends Component {

  showState() {
      console.log(this.store.getState())
  }

  render() {

    const { value, onIncrementClick, onDecrementClick } = this.props

    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title"></h1>
        </header>

      <h2>Counter</h2>

      <div onClick = {onIncrementClick}> <p className="button"> + </p></div>
      <div onClick = {onDecrementClick}> <p className="button"> - </p></div>
      <div onClick = {this.showState}> <p className="button"> Show State </p></div>

    </div>
    );
  }
}

View = connect(
  this.mapStateToProps,
  this.mapDispatchToProps
)(View)

const WrappedApp = () => (
  <Provider store={this.store}>
    <View />
  </Provider>
);

export default WrappedApp;

我现在得到:

Could not find "store" in either the context or props of "Connect(View)". Either wrap the root component in a &lt;Provider&gt;, or explicitly pass "store" as a prop to "Connect(View)".

【问题讨论】:

  • 你能用你的实际NewComponent 显示你的代码吗?现在很难看出你在它和你的 View 组件之间分离了什么,以及它们是如何结合在一起的。
  • @MartinWedvich 已更新。希望它更清楚一点。
  • 请将更新后的代码贴在第一个文件中
  • @Rahamin 添加。

标签: javascript reactjs ecmascript-6 redux react-redux


【解决方案1】:

我敢打赌你有 OOP 语言的技术背景,对吧? :)

React Component 基本上是一个负责在屏幕上渲染某些内容的函数。 如果你想组织你的 Redux 相关代码,你不必将它包装在 React Component 中。只需在单独的文件中声明您需要的函数和对象并使用JavaScript module import/export feature

然后您可以关注guidelines from Redux,了解如何组织您的 Redux 代码。

例如,对于您的 Redux 商店,您最终可以得到一个包含类似内容的 store.js 文件

...
export const store = createStore(reducer);
...

然后只需导入它就可以在您想要的地方使用它

import store from 'store.js'

【讨论】:

  • 啊,完美,现在可以使用了。鉴于 React 实际上是什么,现在您提到它时,这一点非常明显。我大多来自 Python 背景,过去我只玩过一点 Ionic,它似乎需要将所有东西都包装在组件中(尽管我可能错了)。
【解决方案2】:

您不应该像在将代码拆分为两个文件之后那样定义两次存储。并且您定义了一个不是真正组件的组件。而这只是两件不太好的事情......

我不认为修复上述代码是开始构建 react/redux 项目的好方法。以下是一种更好的方法,将来会为您服务:

  1. 首先,下载一个基本的 redux 代码示例。我推荐的一个是ReduxSimpleStarter。这是如何在 redux 项目中组织文件夹树的一个很好的示例。
  2. 查看完上述示例后,使用create-react-app 创建一个新项目,运行它,然后根据 redux 示例开始修改它。

【讨论】:

  • 不确定定义store 两次是什么意思- 我没有。如果您的意思是顶部的某些导入是多余的,我知道这一点,这就是为什么我不想将所有代码粘贴到不同的文件中,因为我匆忙将它们放在一起只是为了测试出概念。我知道这里没有什么是最佳实践。我编写的原始组件也有效,它只是在我尝试将其拆分为不同的组件后才重新调整错误。所以它没有像你暗示的那样有 400 个错误,下面的 Arnauds 简单建议修复了它。不需要关于文件结构的建议,我只是在测试概念。
  • 很好。对不起,如果我侮辱了你,不是故意的,是为了帮助。我真诚的道歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 2019-08-05
  • 2017-01-03
  • 2017-07-24
相关资源
最近更新 更多