#javascript #reactjs
Вопрос:
Я передаю этот объект в качестве опоры компоненту под названием LoungeItem
:
lounge = {guests: [], _id: "60ec3840306969479c25b822", name: "Lounge_name"}
подобный этому:
<LoungeItem lounge={lounge} />
Если я добавлю гостя в lounge.guests
so, это будет выглядеть так:
lounge = {guests: [
{_id: "60e5892d1e8b3c2c24c5463c", name: "username", surname: "usersurname", profile: {…}}
], _id: "60ec3840306969479c25b822", name: "Lounge_name"}
Это изменение не обнаруживается внутри LoungeItem
и componentWillReceiveProps
не срабатывает:
Это компонент:
class LoungeItem extends Component {
componentWillReceiveProps(nextProps) {
console.log(
"🚀 ~ file: LoungeItem.js ~ line 18 ~ LoungeItem ~ componentWillReceiveProps ~ nextProps",
nextProps
);
}
render() {
const { lounge } = this.props;
console.log("===================INSIDE LOUNGE ITEM =================");
console.log(
"🚀 ~ file: PublicLoungeList.js ~ line 7 ~ PublicLoungeList ~ render ~ lounge",
lounge
);
console.log("===================INSIDE LOUNGE ITEM =================");
const guests = lounge.guests;
console.log(
"🚀 ~ file: LoungeItem.js ~ line 33 ~ LoungeItem ~ render ~ guests",
guests
);
return <div>Lounge</div>;
}
}
ПРАВКА 1: Как и было запрошено, вот как lounge изменяется в редукторе:
case JOIN_LOUNGE:
const newLounges = state.lounges.map((lounge) => {
if (lounge._id == action.payload.lounge_id) {
lounge.guests.push({
_id: action.payload._id,
name: action.payload.name,
surname: action.payload.surname,
profile: {
_id: action.payload.profile._id,
handle: action.payload.profile.handle,
},
});
return lounge;
} else {
return lounge;
}
});
И для получения более подробной информации это обрабатывается следующим образом по LoungesList
компонентам:
class LoungesList extends Component {
render() {
const { lounges } = this.props;
console.log(
"===================INSIDE PUBLIC LOUNGE LIST================="
);
console.log(
"🚀 ~ file: PublicLoungeList.js ~ line 7 ~ PublicLoungeList ~ render ~ lounges",
lounges
);
console.log(
"===================INSIDE PUBLIC LOUNGE LIST================="
);
return lounges.map((lounge) => {
console.log(
"🚀 ~ file: PublicLoungeList.js ~ line 19 ~ PublicLoungeList ~ returnlounges.map ~ lounge",
lounge
);
return <LoungeItem lounge={lounge} />;
});
}
}
И этот называется здесь:
class Home extends Component {
render() {
return <PublicLoungeList lounges={this.props.lounges}></PublicLoungeList>;
}
}
const mapStateToProps = (state) => ({
lounges: state.chats.lounges,
});
Комментарии:
1. Как здесь задействован Redux? Я не вижу ничего связанного.
2. Изменение гостей осуществляется с помощью redux. Но я не добавил его сюда, потому что не имеет значения, было ли изменение сделано с помощью redux или самим родительским компонентом.
3. Это может зависеть от того, как вы изменяете свойство, например, если вы изменяете свойство «на месте»
lounge
, это будет один и тот же объект, и может не вызвать обновление.4. Согласованный. Вам нужно убедиться, что вы
lounge
заменяете новый объект (например, используяObject.assign
), а не модифицированную версию в том же месте (например, с помощью назначения на месте). Если вы хотите, чтобы мы помогли, вы должны показать нам код, который обновляетсяlounge
.5. Я просто толкаю гостя в гостиную.гостей. Если это не считается «изменением реквизита», как мне обновить lounge таким образом, чтобы изменения были обнаружены.
Ответ №1:
Вы не должны мутировать lounge.guests
, вместо этого используйте оператор распространения для создания новой гостиной с обновленным массивом
case JOIN_LOUNGE:
const newLounges = state.lounges.map((lounge) => {
if (lounge._id == action.payload.lounge_id) {
return {
...lounge,
guests: [...lounge.guests,{
_id: action.payload._id,
name: action.payload.name,
surname: action.payload.surname,
profile: {
_id: action.payload.profile._id,
handle: action.payload.profile.handle,
},
}]
}
} else {
return lounge;
}
});