#javascript #reactjs #function #components
#javascript #reactjs #функция #Компоненты
Вопрос:
У меня есть родительская компонентная сеть с именем FormLeadBuilderEdit, и именно с помощью useState я передаю функцию setState (setCards в моем случае) в мою дочернюю компонентную сеть с именем Card. По какой-то причине в дочернем компоненте, когда я вызываю setCard («vale»), состояние не обновляется. Поэтому я не уверен, что я делаю неправильно.
Любая помощь была бы отличной
Спасибо
Компонент FormLeadBuilderEdit
import React, { useState, useEffect } from "react";
import { Card } from "./Card";
const FormLeadBuilderEdit = ({ params }) => {
const inputs = [
{
inputType: "shortText",
uniId: Random.id(),
label: "First Name:",
value: "Kanye",
},
{
inputType: "phoneNumber",
uniId: Random.id(),
label: "Cell Phone Number",
value: "2813348004",
},
{
inputType: "email",
uniId: Random.id(),
label: "Work Email",
value: "kanye@usa.gov",
},
{
inputType: "address",
uniId: Random.id(),
label: "Home Address",
value: "123 White House Avenue",
},
{
inputType: "multipleChoice",
uniId: Random.id(),
label: "Preferred Method of Contact",
value: "2813348004",
multipleChoice: {
uniId: Random.id(),
options: [
{
uniId: Random.id(),
label: "Email",
checked: false,
},
{
uniId: Random.id(),
label: "Cell Phone",
checked: false,
},
],
},
},
{
inputType: "dropDown",
uniId: Random.id(),
label: "How did you find us?",
value: "2813348004",
dropDown: {
uniId: Random.id(),
options: [
{
uniId: Random.id(),
label: "Google",
},
{
uniId: Random.id(),
label: "Referral",
},
],
},
},
];
const [cards, setCards] = useState([]);
setCards(inputs)
return (
<>
<Card
key={card.uniId index}
index={index}
id={card.uniId}
input={card}
setCards={setCards}
params={params}
cards={cards}
/>
</>
);
};
export default FormLeadBuilderEdit;
Компонент корзины
import React, { useRef } from "react";
import { Random } from "meteor/random";
export const Card = ({ setCards, cards }) => {
const addOption = () => {
const newCards = cards;
newCards.map((card) => {
if (card.inputType === "multipleChoice") {
card.multipleChoice.options.push({
uniId: Random.id(),
label: "test",
checked: false,
});
}
});
console.log(newCards);
setCards(newCards);
return (
<>
<button onClick={addOption} type="button">
Add Option
</button>
</>
);
};
Комментарии:
1.
map
возвращает новую копию массива. Попробуйте этоconst newCard = ...your card map code; setCards(newCard)
2. Согласно вашей логике,
cards.map
всегда будет возвращать пустой массив, который вы на самом деле не добавляете. никакой опции.
Ответ №1:
React использует ссылку на переменную как способ узнать, какое состояние было изменено, а затем запускает повторный рендеринг.
Итак, первое, что вы хотели бы знать о состоянии, это то, что «Не изменять состояние напрямую».
Ссылка: https://reactjs.org/docs/state-and-lifecycle.html#using-state-correctly
Вместо этого создайте новое состояние, содержащее изменения (с другой ссылкой на переменную) :
const addOption = () => {
const newCards = cards.map((card) => {
if (card.inputType === "multipleChoice") {
const newOption = {
uniId: Random.id(),
label: "test",
checked: false,
};
card.multipleChoice.options = [...card.multipleChoice.options, newOption];
}
return card;
});
setCards(newCards);
// setCards(cards); <- this refer to the current `cards` which will not trigger re-render
};
Комментарии:
1. Я следовал вашему шаблону, но он регистрировался в консоли undefined, поэтому я слегка изменил его, как показано в моем вопросе выше, но мое изменение состояния по-прежнему не перезаписывает мою компонентную сеть
2. Привет, я отредактировал ответ. Я предполагаю, что вы хотите запустить повторный рендеринг массива параметров. Также отмечено, что
map
функция должна что-то возвращать
Ответ №2:
Как указал один из пользователей, вы передаете пустой cards
массив, над которым выполняете map
операцию, которая, что неудивительно, возвращает сам пустой массив, следовательно, вы не получаете никаких изменений состояния.
Логика передачи setCards
правильная.
Вот небольшой пример, в котором происходят изменения состояния, а также показаны.
import React, { useState } from "react";
const App = () => {
const [cards, setCards] = useState([]);
return (
<>
<Card
setCards={setCards}
cards={cards}
/>
<p>{cards.toString()}</p>
</>
);
};
const Card = ({ setCards, cards }) => {
const addOption = () => {
setCards(["1","2"]);
};
return (
<>
<button onClick={addOption} type="button">
Add Option
</button>
</>
);
};
export default App;
Скриншот:
Комментарии:
1. Извините, мой фактический код был намного больше, поэтому я не показал, где я изначально установил состояние. Я добавил свои изменения, описанные выше, он будет регистрировать правильные (новые карточки), но изменение состояния никогда не перезапускает страницу
2. если возможно, рассмотрите возможность публикации этого проекта в CodeSandbox и поделитесь ссылкой
3. хорошо, я попробую, но это проект meteor, поэтому у него есть некоторые зависимости, которые я не уверен, что смогу настроить