【问题标题】:How do i access redux state from another react component?如何从另一个反应组件访问 redux 状态?
【发布时间】:2020-01-18 03:10:54
【问题描述】:

我正在开发一个彩票统计应用程序,该应用程序从从输入加载的 csv 获取数据,然后我想将这些数据读取到 redux 存储,以便我可以在多个组件中使用它。

导入文件并通过 Header.js 读取并使用操作后,我已成功将数据保存到 redux 存储,但我不确定如何在其他组件中访问它,例如主.js。

我觉得我仍然对 react/redux 如何组合在一起感到困惑。很抱歉,如果以前有人问过这个问题,但是我在网上查到的所有内容都无法开始工作。

// index.js

import React from "react";
import ReactDOM from "react-dom";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import reducers from "./reducers";

import App from "./components/App";

const store = createStore(reducers, applyMiddleware(thunk));

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector("#root")
);
// App.js

import React from "react";

import Header from "./Header";
import Main from "./Main";

const App = () => {
  return (
    <div>
      <Header />
      <Main />
      <div className="numbers-for-draw"></div>
    </div>
  );
};

export default App;
// Header.js

import React from "react";
import { CSVReader } from "react-papaparse";
import { fetchData } from "../actions";
import { connect } from "react-redux";

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.fileInput = React.createRef();
  }

  handleReadCSV = data => {
    this.props.fetchData(data);
    console.log(this.props.data);
  };

  handleOnError = (err, file, inputElem, reason) => {
    console.log(err);
  };

  handleImportOffer = () => {
    this.fileInput.current.click();
    console.log("Got to handleImportOffer");
  };

  render() {
    return (
      <header>
        <CSVReader
          onFileLoaded={this.handleReadCSV}
          inputRef={this.fileInput}
          style={{ display: "none" }}
          onError={this.handleOnError}
        />
        <button onClick={this.handleImportOffer}>Import</button>
      </header>
    );
  }
}

//Map what is in the redux store (e.g. state) to props
const mapStateToProps = state => ({
  data: state.data
});

export default connect(mapStateToProps, {
  fetchData: fetchData
})(Header);
// Main.js

import React from "react";

import { fetchData } from "../actions";
import { connect } from "react-redux";

const Main = () => {
  console.log("In main");
  console.log(this.props.data);  //Blows up here. 
  return <div>Main</div>;
};

//Map what is in the redux store (e.g. state) to props
const mapStateToProps = state => ({
  data: state.data
});

export default connect(mapStateToProps, {
  fetchData: fetchData
})(Main);
// actions/index.js

export const fetchData = data => dispatch => {
  console.log("Action");
  const lottoData = {
    stringNumbers: [
      "one",
      "two",
      "three",
      ...
    ],

    allResults: [],
    winningNumbers: [],
    winningNumbersAsStrings: []
  };

  const localData = data.data;
  localData.shift();

  localData.forEach(line => {
    const lineObject = {
      draw: line[0],
      drawDate: line[1],
      ballOne: line[2],
      ballTwo: line[3],
      ballThree: line[4],
      ballFour: line[5],
      ballFive: line[6],
      ballSix: line[7],
      bonusBall: line[8],
      bonusBall2: line[9],
      powerBall: line[10]
    };

    lottoData.allResults.push(lineObject);

    let nums = [];
    nums.push(parseInt(line[2]));
    nums.push(parseInt(line[3]));
    nums.push(parseInt(line[4]));
    nums.push(parseInt(line[5]));
    nums.push(parseInt(line[6]));
    nums.push(parseInt(line[7]));

    nums.sort((a, b) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });

    lottoData.winningNumbers.push(nums);
    lottoData.winningNumbersAsStrings.push(nums.toString());
  });

  dispatch({ type: "FETCH_DATA", payload: lottoData });
};

// lottoReducer.js

export default (state = {}, action) => {
  switch (action.type) {
    case "FETCH_DATA":
      return action.payload;
    default:
      return state;
  }
};
// reducers/index.js

import { combineReducers } from "redux";
import lottoReducer from "./lottoReducer";

export default combineReducers({
  data: lottoReducer
});

【问题讨论】:

  • 请参阅下面的答案。访问功能组件中的道具。具体来说,您应该这样做:const Main = (props) =&gt; { console.log(props.data); return &lt;div&gt;Main&lt;/div&gt;; };

标签: javascript reactjs redux react-redux


【解决方案1】:

我没有测试过你的代码,但在我看来唯一的问题在于你的Main.js

虽然您使用 function component 而不是类,但您不应该使用 this 来访问您的道具。以下应按预期工作:

const Main = (props) => {
  console.log("In main");
  console.log(props.data);  
  return <div>Main</div>;
};

//Map what is in the redux store (e.g. state) to props
const mapStateToProps = state => ({
  data: state.data
});

export default connect(mapStateToProps, {
  fetchData: fetchData
})(Main);

【讨论】:

  • 谢谢米卡利斯。希望这是一件简单的事情。我仍然需要在我的 Main.js 组件中使用 connect 函数和 mapStateToProps 不是吗?
  • 是的,没错!但是,如果您在此组件中不需要它,则可以删除 connect 的第二个参数(具有 fetchData 操作的对象)。 :)
【解决方案2】:

在您的 main.js 中,您使用了功能组件,因此 this.props 在那里不起作用。您必须将道具传递给您的组件和console.log(props.data)

【讨论】:

    猜你喜欢
    • 2021-08-07
    • 2017-04-02
    • 2022-11-27
    • 1970-01-01
    • 2022-11-21
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    相关资源
    最近更新 更多