Я новичок в ReactJS и все еще пытаюсь понять жизненный цикл компонентов. Я пытался установить значение по умолчанию для мультиреактивного выбора в течение некоторого времени, но каким-то образом это просто не работает. Поскольку я в точности следую документации ' реагировать на выбор ', я думаю, что моя проблема связана с жизненным циклом компонентов React.
Что я пытаюсь to do: Цель состоит в том, чтобы создать экран редактирования пользователя. Мультивыбор - это то место, где будут установлены технологии, с которыми работает Пользователь. У одного пользователя может быть много техников.
(я публикую здесь только код, связанный с проблемой, чтобы облегчить понимание моей проблемы)
Получение всех 'техников 'из базы данных:
const [allTechs, setAllTechs] = useState([]);
useEffect(() => {
async function getAllTechs(){
const response = await api.get('/api/techs');
return response.data.docs;
}
getAllTechs().then(result => {
const list = [];
result.forEach(r => {
let tech = {value: r._id, label: r.name};
list.push(tech);
})
setAllTechs(list);
});
}, []);
Получение технических данных пользователя из базы данных:
const [techs, setTechs] = useState([]);
let { id } = useParams();
useEffect(() => {
async function getData() {
const response = await api.get(`api/users/${id}`);
return response.data;
}
getData().then(result => {
setTechs(result.techs);
});
}, []);
После этого я создаю состояние под названием' userTechsForSelect ', который должен быть массивом объектов. Эти объекты должны иметь только 2 атрибута: «значение» и «метка», так же как и состояние «allTechs», потому что это атрибуты, которые «реагирует на выбор» запрашивает в своей документации. (https://react-select.com/home)
Заполнение 'userTechsForSelect':
const [userTechsForSelect, setUserTechsForSelect] = useState([]);
useEffect(() => {
async function getInitialTechValues(){
const list = [];
techs.map(t => {
let tech = {value: t._id, label: t.name};
list.push(tech);
})
setUserTechsForSelect(list);
}
getInitialTechValues();
}, [techs]);
Теперь, когда я создаю 'Select' на моем компоненте, Я использую упомянутые ранее состояния ( 'allTechs' как 'опции' и 'userTechsForSelect' как 'defaultValue' ), чтобы установить его атрибуты:
return(
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={userTechsForSelect[0]}
closeMenuOnSelect={false}
placeholder="Select"
isMulti
styles={colourStyles}
/>
)
Параметры устанавливаются, но значение по умолчанию - нет. Я предполагаю, что компонент «Выбрать» визуализируется до того, как «userTechsForSelect» получит свои значения. Но если перед тегом 'Select' поставить ' console.log (userTechsForSelect) ', я могу видеть, что компонент рендерится много раз, и хотя состояние пусто при первом рендеринге, это не на последних.
Компонент точно так, как он отображается: [Img] Выбрать
Console.log результат : [Img] Console.log
Кто-нибудь может мне помочь и сказать, почему не устанавливаются значения по умолчанию? Если вы хотите, чтобы я опубликовал любой другой код, просто спросите! Спасибо !
Редактировать 1:
Даже когда я помещаю defaultValue
выбора в виде массива , он не отображает технику, которой обладает пользователь.
<label className="editUserLabel">Tecnologias
{console.log(userTechsForSelect[0])}
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={[userTechsForSelect[0]]}
closeMenuOnSelect={false}
placeholder="Selecione"
isMulti
styles={colourStyles}
/>
</label>
Но когда я заменяю defaultValue
на фиксированный объект (как я показываю ниже), он работает (даже если я не надену не помещайте это как массив, как defaultValue={exampleValue[0]}
)
const exampleValue = [{value: '5e6067ddef8a973de092403d', label: 'NodeJS'}];
return(
<label className="editUserLabel">Tecnologias
{console.log(userTechsForSelect[0])}
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={exampleValue[0]}
closeMenuOnSelect={false}
placeholder="Selecione"
isMulti
styles={colourStyles}
/>
</label>
)
Результат: здесь
Edit 2:
Как я и просил, я собираюсь console.log
options
State и defaultValue
State перед выбором, так что вы можете видеть, что defaultValue
должен соответствовать одному из вариантов.
Код:
<label className="editUserLabel">Tecnologias
{console.log("allTechs: ")}
{console.log(allTechs)}
{console.log("userTechsForSelect: ")}
{console.log(userTechsForSelect)}
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={[userTechsForSelect[0]]}
closeMenuOnSelect={false}
placeholder="Selecione"
isMulti
styles={colourStyles}
/>
</label>
(console.log
появятся много раз, потому что компонент также рендерится много раз, поэтому я ставлю еще console.log
перед каждым, чтобы его было легче видеть)
Результат: [Img] console.log results
Как видите, массив userTechsForSelect
в начале пуст, но тогда это не так. Я думаю, что компонент Select
рендерится до того, как userTechsForSelect
получит свои значения