如何在多个组件中共享redux store [英] How to share redux store in multiple components

查看:86
本文介绍了如何在多个组件中共享redux store的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hi I have one component in which I integrated the redux in my react application. I am opening second then third component. I don't want the pass the data which I obtained in first component to second then third in props.

我想使用redux store执行此操作。有没有办法做到这一点?

I want to do this using redux store. Is there any way to do this ?

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);

index.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();

secondcomponent.js

secondcomponent.js

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

third component.js

third component.js

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

什么方式可以访问redux store多个组件?

Whats the way to have an access of redux store in multiple components ?

推荐答案

包含 connect 的任何组件

connect(mapStateToProps, actions)(AnyComponent);

可以访问整个 redux store。

使用 mapStateToProps ,您可以传递来自 redux 通过 props 存储到连接的组件。

will have access to the entire redux store.
With mapStateToProps you can pass just relevant piece of data from the redux store to the connected component via props.

关于组件内部,我的经验法则是为内容状态设置仅适用于与特定组件。

例如, extend collapse 状态为下拉列表。

About component internal state, my rule of thumb is to set internal state just for data that is relevant for the specific component.
For example, extend or collapse state for a Drop-down.

至于 ajax 请求,如果你已经使用 redux 我强烈建议使用 thunks sagas 的操作,并通过 redux 流量:

动作/ thunk - > Reducers - >连接组件。

As for ajax requests, if you already using redux I highly recommend to use actions with thunks or sagas and pass the new fetched data through the redux flow:
Action/thunk -> Reducers -> connected components.

编辑


作为评论的后续内容,

您无需传递要连接到提供商的每个组件,只需通过根组件(在您的情况下为 App )并且 App 的每个子节点都可以连接到 redux 如有必要:

Edit
As a followup to your comment,
You don't need to pass every component you want to connect to the Provider, you just pass a root component (App in your case) and each child of App can connect to redux if necessary:

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

作为后续行动您的其他评论:

Edit #2
As a followup to your other comment:


因此将道具中的值传递给组件或使用上述方法,建议使用
Idk?

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

尽可能避免连接组件并将道具传递给孩子,主要原因是为了防止依赖 redux

我更喜欢让我的组件笨拙,让他们只关注事物的外观。

我确实有一些关于事物如何工作的组件,这些组件主要处理逻辑并将数据传递给子节点,它们是我经常连接的组件。

Avoid connecting components when you can and pass down the props to the children, the main reason for this is to prevent dependency on redux.
I prefer keep my components "dumb" as i can and let them concern only on how things should look.
I do have some components that concern on how things should work and these components are mainly dealing with logic and passing down data to the children, they are the components i often connect.

当我注意到我的应用程序正在缩放并且我的一些组件充当道具的代理时(我甚至得到了一句话!Propxy),他们是从父母那里得到道具并将它们传递下来而不使用它们,我通常在组件树的中间注入一个连接组件,这样我就可以让树下流动的propxy组件变得更加轻盈和纤细。

When i notice that my app is scaling and some of my components are acting as a proxy of props (i even got a word for that! "Propxy"), that is they get props from their parent and pass them down without using them, i usually inject a connected component in the middle of the components tree so i can let the "propxy" components down the tree flow be more lighten and slim.

这篇关于如何在多个组件中共享redux store的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆