我是ReactJS的新手,但我仍在尝试了解组件的生命周期。我一直在尝试将multi react-select的默认值设置为一段时间,但是以某种方式根本无法正常工作。由于我完全按照“ react-select ”文档中的说明进行操作,因此我认为我的问题与React的组件生命周期有关。
我要做什么: 目的是制作一个“编辑用户”屏幕。多选是设置用户使用技术的地方。一个用户可以拥有很多技术。
(我仅在此处发布与问题相关的代码,使我的问题更易于理解)
从数据库中获取所有“技术”:
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”的州一样,“因为这些是'react-select'在其文档中要求的属性。 (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]);
现在,当我在组件上初始化“选择”时,我将使用前面提到的状态(“ allTechs”作为“选项” 和 'userTechsForSelect '作为'defaultValue')来设置其属性:
return(
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={userTechsForSelect[0]}
closeMenuOnSelect={false}
placeholder="Select"
isMulti
styles={colourStyles}
/>
)
正在设置选项,但默认值不是。我的猜测是:“选择”组件在“ userTechsForSelect”接收其值之前被渲染。但是,如果在“选择”标记之前放置“ console.log(userTechsForSelect)”,我可以看到该组件被渲染了很多次,并且在第一次渲染时该状态为空。不是最后一个。
组件的呈现方式完全相同: [Img]Select
Console.log结果: [Img]Console.log
任何人都可以帮助我,并告诉我为什么未设置默认值吗?如果您要我发布其他任何代码,请问! 谢谢!
编辑1:
即使我将Select的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]}
那样将其放置为数组)< / p>
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>
)
结果是: here
编辑2:
根据要求,我将在选择之前进入console.log
状态和options
状态,因此您可以看到defaultValue
应该与选项之一。
代码:
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
,以便于查看)>
如您所见,userTechsForSelect
数组在开始时为空,但随后不是。我认为Select
组件是在userTechsForSelect
获得其值之前呈现的
答案 0 :(得分:0)
由于您已传递isMulti
为真,因此您的defaultValue
应该是一个数组
defaultValue={[userTechsForSelect[0]]}
答案 1 :(得分:0)
我刚刚解决了!
正如我所怀疑的那样,该组件是在userTechsForSelect
具有任何值之前渲染的。因此,我创建了一个function
来验证userTechsForSelect.length > 0
是否仅在满足此条件的情况下才返回组件
function EditUser() {
// All useStates and useEffects that I posted before
// What I modified:
function createReactSelect(){
if (userTechsForSelect.length > 0){
return (
<label className="editUserLabel">Tecnologias
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={[userTechsForSelect[0]]}
closeMenuOnSelect={false}
placeholder="Selecione"
isMulti
styles={colourStyles}
/>
</label>
);
}
}
return {createReactSelect()};
}
export default EditUser;