- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将一个元素添加到我的 Redux 存储中对象的数组中。我看到对象已添加到商店,但它没有更新组件。如果我离开页面并返回它就会出现。
我很确定这是一个状态突变问题,但我无法弄清楚我哪里出错了,除非我从根本上误解了 Immer 在做什么。在组件中,我使用 produce 将字符串添加到数组,将新对象传递到我的 reducer 并使用 produce 将该对象添加到这些对象的数组。
我已经查看了大量与状态突变相关的类似问题,但我的理解方式是组件调用 produce 的返回应该是一个全新的对象。然后在 reducer 中对 produce 的调用应该返回一个新的对象数组。
这是第一次在大型项目中使用 Immer,所以我完全有可能不完全了解它的工作原理。
Component
import produce from 'immer';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import uuid from 'uuid/v4';
import { generate } from 'generate-password';
import { updateLeague } from '../../actions/leagues';
import { addTeam } from '../../actions/teams';
import { addUser } from '../../actions/users';
import Team from '../../classes/Team';
import User from '../../classes/User';
import UserWidget from '../utils/user/UserWidget';
class ViewLeague extends Component {
state = {
league : null,
isOwner : false,
owner : '',
teams : [],
inviteEmail: ''
};
componentWillMount() {
console.log('mount props', this.props.leagues);
const { leagues, uuid, leagueId, users, teams } = this.props;
if (leagues.length > 0) {
const league = leagues.find(league => league.uuid === leagueId);
const owner = users.find(user => league.leagueManager === user.uuid);
const leagueTeams = teams.filter(team => league.teams.includes(team.uuid));
this.setState({
league,
isOwner: league.leagueManager === uuid,
owner,
teams : leagueTeams
});
}
}
handleUpdate(event, fieldName) {
this.setState({ [ fieldName ]: event.target.value });
}
findUserByEmail(email) {
//Todo if not found here hit server
return this.props.users.find(user => user.email === email);
}
sendInvite = () => {
const { addTeam, addUser, updateLeague } = this.props;
const { league } = this.state;
const newManager = this.findUserByEmail(this.state.inviteEmail);
const newTeamUuid = uuid();
let newLeague = {};
if (newManager) {
const newTeam = new Team('New Team', newManager.uuid, newTeamUuid);
addTeam(newTeam);
} else {
const newPass = generate({
length : 10,
number : true,
uppercase: true,
strict : true
});
const newUserUuid = uuid();
const newUser = new User('', this.state.inviteEmail, newPass, '', '', newUserUuid);
addUser(newUser);
const newTeam = new Team('New Team', newUserUuid, newTeamUuid);
addTeam(newTeam);
newLeague = produce(league, draft => {draft.teams.push(newTeamUuid);});
updateLeague(newLeague);
console.log('invite props', this.props);
console.log('league same', league === newLeague);
}
//Todo handle sending email invite send password and link to new team
console.log('Invite a friend', this.state.inviteEmail);
};
renderInvite() {
const { isOwner, league, teams } = this.state;
if (isOwner) {
if ((league.leagueType === 'draft' && teams.length < 8) || league.leagueType !== 'draft') {
return (
<div>
<p>You have an empty team slot. Invite a fried to join!</p>
<input type="text"
placeholder={'email'}
onChange={() => this.handleUpdate(event, 'inviteEmail')}/>
<button onClick={this.sendInvite}>Invite</button>
</div>
);
}
}
}
renderViewLeague() {
console.log('render props', this.props.leagues);
const { league, owner, teams } = this.state;
const editLink = this.state.isOwner ?
<Link to={`/leagues/edit/${this.props.leagueId}`}>Edit</Link> :
'';
return (
<div>
<h2>{league.leagueName} </h2>
<h3>League Manager: <UserWidget user={owner}/> - {editLink}</h3>
<p>League Type: {league.leagueType}</p>
{this.renderInvite()}
<br/>
<hr/>
<h2>Teams</h2>
<span>{teams.map((team) => (<p key={team.uuid}>{team.teamName}</p>))}</span>
<span>
<h2>Scoring: </h2>
{league.scoring.map((score, index) => (
<p key={index}>{`Round ${index + 1}: ${score} points`}</p>
)
)}
</span>
</div>
);
}
render() {
if (!this.state.league) {
return (
<div>
<h2>No league Found</h2>
</div>
);
} else {
return (
<div>
{this.renderViewLeague()}
</div>
);
}
}
}
export default connect(
({ leagues: { leagues }, teams: { teams }, users: { users }, auth: { uuid } },
{ match: { params: { leagueId } } }) => ({
leagues,
teams,
users,
uuid,
leagueId
}), ({
addTeam : (team) => addTeam(team),
addUser : (user) => addUser(user),
updateLeague: (league) => updateLeague(league)
})
)(ViewLeague);
Reducer
import produce from 'immer';
import {
ADD_LEAGUE,
UPDATE_LEAGUE
} from '../actions/types';
const DEFAULT_LEAGUES = {
leagues: [ {
leagueName : 'Test League',
leagueManager: 'testUser12345',
uuid : 'testLeague12345',
teams : [ 'testTeam12345', 'testTeam23456' ],
scoring : [ 25, 20, 15, 10, 5, -5 ],
leagueType : 'draft'
} ]
};
const leaguesReducer = (state = DEFAULT_LEAGUES, action) =>
produce(state, draft => {
// noinspection FallThroughInSwitchStatementJS
switch (action.type) {
case ADD_LEAGUE:
draft.leagues.push(action.league);
case UPDATE_LEAGUE:
console.log('updating league', action.league);
const { league } = action;
const leagueIndex = draft.leagues.findIndex(fLeague => league.uuid === fLeague.uuid);
draft.leagues.splice(leagueIndex, 1, league);
}
});
export default leaguesReducer;
非常感谢任何帮助!!如果需要,可提供更多信息
最佳答案
尝试在案例 block 的末尾添加 return;
。
您可以阅读有关从生产者返回数据的更多信息,并查看该做什么和不该做什么的示例 here .
关于reactjs - 带有 Immer 的 Redux 不更新组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54729366/
我正在尝试使用从服务器获取的一组数据来更新一段状态。这是我的 reducer : const schoolsDataReducer = (state = { data: [] }, action) =
不知道为什么连我都修改了草稿,immer没有给我提供新的状态,而是修改了内容的旧状态实例。 import CartItem from "../../models/cart-item"; import
我开始使用 Immer.js 以实现 JS 中的不变性,但我找不到使用过滤器方法删除数组中对象的方法。它返回相同的对象。顺便说一句,我在 React 中使用状态来做这件事,但为了让它更直接,我编写了反
我正在使用最新版本的 immer(6.0.5) - https://www.npmjs.com/package/immer它似乎不适用于 IE11 。在控制台中得到一个神秘的错误 有没有办法让“imm
我正在使用 immer在 react 应用程序中处理状态更改。假设状态没有像我预期的那样改变,所以我想调试它,但是 console.log和 debugger给出 Proxy不包含任何有用信息的对象,
//I want my action to dispatch payload like // {type:'update',payload:{'current.contact.mobile':'XXX
我想知道是否可以在一次“调用”中使用 immer.js 更新状态的多个属性。 假设我有状态: export const initialState = { isUserLogged: false,
为什么我的 immer reducer 没有返回新值,即使 reducer 内部的吃水已经改变?我正在使用 console.log 检查我的草稿是否在 immerReducer 中被更改: // in
我正在尝试将一个元素添加到我的 Redux 存储中对象的数组中。我看到对象已添加到商店,但它没有更新组件。如果我离开页面并返回它就会出现。 我很确定这是一个状态突变问题,但我无法弄清楚我哪里出错了,除
Redux Style-Guide状态: Avoid putting non-serializable values such as Promises, Symbols, Maps/Sets, fun
import produce from "immer"; const initialState = { isLoading: true, error: "", burgers: [], }
我正在开发一个 React 项目并使用 Redux 进行状态管理。我正在从 ImmutableJS 转移到 Immer,我不确定如何通过一些更改返回初始状态。我正在使用来自 ImmutableJS 的
我有一个调用handleApplyFiltersButtonClick 的按钮,它通过将过滤器应用于某些数据来更新状态。我的某个地方有一个错误。我正在努力调试使用 Immers 产品的状态,因为一切都
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 3 年前。 Improve th
我正在使用 immer转换 react/redux 状态。我还可以使用 immer 只深度复制一个对象而不对其进行转换吗? import produce, {nothing} from "immer"
安装 react-router-dom 后。 我发现我有一个弱点。 正是这样: 我没有找到太多有用的信息来解决。有没有人遇到过这个问题? 最佳答案 作为临时解决方法,直到第三方包将其依赖项更新为最新的
Eslint 总是提示 Unallowed reassignment from fp/no-mutation rule for basic immer 构造: const nextState = pr
查看 redux 和 ngrx,immer 似乎是在存储之前生成状态副本的推荐库。按照 immer 示例,我将以下代码添加到我的 reducer 中: on(exampleActions.upda
我正在使用 redux-starter-kit(其中包括用于可变更新的 Immer 库)并且由于某种原因这个 reducer 不起作用: reInitializeState(state, action
我正在尝试在 Typescript 项目中将 Immer 与 Redux 结合使用。 Redux reducer 可以输入为: Reducer 我应该能够用 Immer's produce funct
我是一名优秀的程序员,十分优秀!