reactjs - 在 React/Redux 中的组件之间传递数据
问题描述
我是 React 的新手,正在尝试构建一个应用程序,将足球运动员分成两支球队,并且在将数据从一个组件传递到另一个组件时遇到困难。
我安装了 redux 和 react-redux。
在我的 reducer.js 中,我获取了一个玩家列表并将它们打乱,将打乱的列表添加到状态:
const shufflePlayers = (state) => {
return {
...state,
shuffledList: [
...state.playersList.sort(() => Math.random() - 0.5)
]
}
}
然后在“src/components/DisplayTeams.index.js”中,我将“shuffledList”数组映射到道具:
import { connect } from "react-redux";
import DisplayTeams from "./DisplayTeams";
const mapStateToProps = (state) => {
return {
shuffledList: state.shuffledList,
};
};
export default connect(mapStateToProps)(DisplayTeams);
最后,在“src/components/DisplayTeams.js”中,我尝试在列表中呈现“shuffledList”数组:
import React from 'react';
import '../../App.css';
const DisplayTeams = ({ shuffledList }) => (
<div>
<ul>
{shuffledList.map((player, index) => (
<li key={index}>{player.name}</li>
))}
</ul>
</div>
);
export default DisplayTeams;
但我收到 TypeError: Cannot read property 'map' of undefined,表明 'shuffledList' 数组为空或根本没有设置。
任何帮助都感激不尽!!
解决方案
您不应该在状态下复制数据,列表和 shuffledList 是相同的数据,但 shuffledList 是列表的计算结果。
您可以使用选择器从列表中计算混洗列表,以防止它在渲染上重新计算您可以使用重新选择(无论如何都应该使用它)并记住混洗结果,只要列表不改变。
const { Provider, useSelector } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
const { createSelector } = Reselect;
const initialState = {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
};
const reducer = (state = initialState) => state;
//selectors
const selectList = (state) => state.list;
//if state.list changes then it will shuffle again
const selectShuffledList = createSelector(
[selectList],
(list) => [...list].sort(() => Math.random() - 0.5)
);
const selectTeams = createSelector(
[selectShuffledList, (_, size) => size],
(shuffledList, teamSize) => {
const teams = [];
shuffledList.forEach((item, index) => {
if (index % teamSize === 0) {
teams.push([]);
}
teams[teams.length - 1].push(item);
});
return teams;
}
);
const selectTeamsCurry = (teamSize) => (state) =>
selectTeams(state, teamSize);
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
initialState,
composeEnhancers(
applyMiddleware(() => (n) => (a) => n(a))
)
);
const App = () => {
//you can re render app with setCount
const [count, setCount] = React.useState(0);
//setting count has no effect on teams because
// state.list didn't change and selectShuffledList
// will use memoized shuffled result
const teams = useSelector(selectTeamsCurry(3));
return (
<div>
<button onClick={() => setCount((w) => w + 1)}>
re render {count}
</button>
<pre>{JSON.stringify(teams, undefined, 2)}</pre>
</div>
);
};
ReactDOM.render(
<Provider store={store}>
<App />
</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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
<div id="root"></div>
推荐阅读
- php - 我的表单中有 3 个日期范围选择器我想存储 00-00-0000 00-00-0000
- c - 具有无限多(未命名)参数的函数 - 如何正确访问这些参数?
- reactjs - 构建 react-app 的意外结果
- ios - 如何在 Swift 中使用可解码?
- c++ - 如何在 iOS 上跟踪 C++ 内存分配?
- c# - 需要 C# datagrid 视图中 Quantity 列的默认值的帮助,它应该是可变的
- android-studio - Android Studio 3.2.1 找不到资源错误
- javascript - sqlite3 插入或更新
- directx - DirectX 11 ID3DDevice::CreateTexture2D 初始数据失败
- python - 如何恢复 rsa 公钥?或在python中将字节更改为rsa公钥?