【发布时间】:2020-03-13 21:08:31
【问题描述】:
我是 ReactJS 的新手,我仍在尝试了解组件的生命周期。一段时间以来,我一直在尝试设置多反应选择的默认值,但不知何故它根本不起作用。由于我完全按照“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 个属性:'value' 和 'label',就像国家称为 '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 ' as 'defaultValue') 来设置它的属性:
return(
<Select
className="editUserReactSelect"
options={allTechs}
defaultValue={userTechsForSelect[0]}
closeMenuOnSelect={false}
placeholder="Select"
isMulti
styles={colourStyles}
/>
)
正在设置选项,但未设置默认值。我的猜测是:在 'userTechsForSelect' 接收到它的值之前,'Select' 组件正在被渲染。但是,如果在 'Select' 标记之前放置一个 '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]})
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:
按照要求,我将在 Select 之前转到 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 获取其值之前被渲染
【问题讨论】:
-
你能添加
userTechsForSelect和allTechs的样子吗? -
您应该编辑此帖子以添加上下文,而不是发布答案。我之所以问是因为我很好奇
userTechsForSelect[0]中的对象的value是否与allTechs中的任何value匹配。 -
抱歉,我没有看到“编辑”按钮,我从现在开始编辑。
标签: reactjs react-hooks react-select