javascript - 如何在多个组件中共享 redux store

标签 javascript reactjs react-native redux react-redux

您好,我有一个组件,我将 redux 集成到我的 React 应用程序中。我打开第二个然后是第三个组件。我不希望将我在第一个组件中获得的数据传递给 Prop 中的第二个然后第三个。

我想使用 redux store 来做到这一点。有什么办法可以做到这一点吗?

App.js

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import RoundedButton from "./RoundedButton";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import * as actions from "./actions/index";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      score: 0,
      status: "",
      userSelected: "",
      computerSelected: "",
      visibility: [true, true, true],
      buttonVisibility: false
    };
    this.clickitem = this.clickitem.bind(this);
    this.handlePlayAgain = this.handlePlayAgain.bind(this);
  }

  handlePlayAgain() {
    this.setState({
      buttonVisibility: false,
      visibility: [true, true, true]
    });
  }

  clickitem(user) {
    var url = "http://localhost:4000/generate-random";
    this.setState({ userSelected: user });

    fetch(url)
      .then(response => {
        if (response.status >= 400) {
          throw new Error("Bad response from server");
        }
        return response.json();
      })
      .then(data => {
        var computer = data.item;
        this.setState({ computerSelected: computer });
        if (
          (user === "Rock" && computer === "Scissors") ||
          (user === "Paper" && computer === "Rock") ||
          (user === "Scissors" && computer === "Paper")
        ) {
          this.props.increment();
        } else if (user === computer) {
          this.props.doNothing();
        } else {
          this.props.decrement();
        }

        console.log(user + " " + computer);
        console.log("------------------------------------");

        App.contextTypes = { store: React.PropTypes.object };
        let store = this.context.store;
        console.log(store);

        arrayvar = [];

        var arrayvar = [];
        if (user === "Rock" && computer === "Rock") {
          arrayvar = [true, false, false];
        } else if (user === "Paper" && computer === "Paper") {
          arrayvar = [false, true, false];
        } else if (user === "Scissors" && computer === "Scissors") {
          arrayvar = [false, false, true];
        } else if (
          (user === "Rock" && computer === "Paper") ||
          (user === "Paper" && computer === "Rock")
        ) {
          arrayvar = [true, true, false];
        } else if (
          (user === "Rock" && computer === "Scissors") ||
          (user === "Scissors" || computer === "Rock")
        ) {
          arrayvar = [true, false, true];
        } else if (
          (user === "Paper" && computer === "Scissors") ||
          (user === "Scissors" || computer === "Paper")
        ) {
          arrayvar = [false, true, true];
        }
        this.setState({ visibility: arrayvar });
        this.setState({
          buttonVisibility: true
        });
      });
  }

  render() {
    return (
      <div className="CenterDiv">
        <div className="AppTitle">
          <b>Score: {this.props.score}</b>
          <div>
            {this.state.visibility[0]
              ? <RoundedButton
                  text="Rock"
                  clickitem={this.clickitem}
                  label={
                    this.state.userSelected === "Rock" &&
                      this.state.computerSelected === "Rock"
                      ? "User & Computer Selected"
                      : this.state.userSelected === "Rock"
                        ? "User Selected"
                        : this.state.computerSelected === "Rock"
                          ? "Computer Selected"
                          : ""
                  }
                />
              : null}
            {this.state.visibility[1]
              ? <RoundedButton
                  text="Paper"
                  clickitem={this.clickitem}
                  label={
                    this.state.userSelected === "Paper" &&
                      this.state.computerSelected === "Paper"
                      ? "User & Computer Selected"
                      : this.state.userSelected == "Paper"
                        ? "User Selected"
                        : this.state.computerSelected === "Paper"
                          ? "Computer Selected"
                          : ""
                  }
                />
              : null}
            {this.state.visibility[2]
              ? <RoundedButton
                  text="Scissors"
                  clickitem={this.clickitem}
                  label={
                    this.state.userSelected === "Scissors" &&
                      this.state.computerSelected === "Scissors"
                      ? "User & Computer Selected"
                      : this.state.userSelected === "Scissors"
                        ? "User Selected"
                        : this.state.computerSelected === "Scissors"
                          ? "Computer Selected"
                          : ""
                  }
                />
              : null}
          </div>

          <div className="Status">{this.props.status}</div>

          {this.state.buttonVisibility
            ? <button onClick={this.handlePlayAgain} style={{ margin: 30 }}>
                Play Again
              </button>
            : null}

        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return { score: state.score, status: state.status };
}

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

索引.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import "./index.css";

import { Provider } from "react-redux";
import { createStore } from "redux";
import scoreReducer from "./reducers";

let store = createStore(scoreReducer);

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

第二个组件.js

export default class SecondComponent extends Component {
  render() {
    return (
       // print score which is in redux
    );
  }
}

第三个组件.js

export default class ThirdComponent extends Component {
  render() {
    return (
       // print score which is in redux
    );
  }
}

如何在多个组件中访问 redux store?

最佳答案

任何connect包装的组件:

connect(mapStateToProps, actions)(AnyComponent);

将有权访问整个 redux 商店。
使用 mapStateToProps,您可以通过 props 将相关数据从 redux 存储传递到连接的组件。

关于组件内部state,我的经验法则是只为与特定组件相关的数据设置内部状态。
例如,下拉菜单的 extendcollapse 状态。

至于 ajax 请求,如果你已经在使用 redux 我强烈建议使用带有 thunkssagas 的 Action > 并通过 redux 流传递新获取的数据:
Action/thunk -> Reducers -> connected components。

编辑
作为您评论的跟进,
您不需要将要连接的每个组件都传递给 Provider,您只需传递一个根组件(在您的情况下为 App),App 的每个子组件都可以连接如有必要,redux:

class SecondComponent extends Component {
  render() {
    return (
       // print score which is in redux
       <div>this.props.score</div> 
    );
  }
} 

export default connect(mapStateToProps)(SecondComponent);

以及其他组件:

class ThirdComponent extends Component {
  render() {
    return (
       // print score which is in redux
       <div>this.props.score</div> 
    );
  }
} 

export default connect(mapStateToProps)(ThirdComponent);

编辑 #2
作为您其他评论的跟进:

so passing value in props to components or use above said approach, Idk which is recommended ?

尽可能避免连接组件,并将 props 传递给 child ,这样做的主要原因是防止对 redux 的依赖。
我更喜欢尽可能让我的组件保持“愚蠢”,让它们只关心事物的外观。
我确实有一些组件关注事情应该如何工作,这些组件主要处理逻辑并将数据传递给 child ,它们是我经常连接的组件。

当我注意到我的应用程序正在缩放并且我的一些组件正在充当 props 的代理时(我什至得到了一个词!“Propxy”),即他们从他们的父级获取 props 并在没有的情况下将它们传递下去使用它们,我通常在组件树的中间注入(inject)一个连接的组件,这样我就可以让树下的“propxy”组件流动得更轻、更细。

关于javascript - 如何在多个组件中共享 redux store,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46797354/

相关文章:

javascript - 获取视频帧数 HTML

javascript - p5.j​​s:当 div 改变高度时调整 Canvas 高度

javascript - Keccak 谈 React-Native

android - 使用 gradlew assembleRelease 从 native react 创建发布 apk 时出错

javascript - 具有样式属性的 jQuery clone 克隆元素

javascript - 在 Firefox 或 Edge 中从缓存预加载图像时出现问题

javascript - 如何在 react router dom v4 中获取组件中的参数?

javascript - 如何从 Firebase 存储获取 React.js 的异步图像数据?

reactjs - App.js 文件中的 function App() 与 class App extends Component

reactjs - React 功能组件中的 async/await