【问题标题】:How to set the 'defaultValue' of 'react-select' multi?如何设置'react-select' multi的'defaultValue'?
【发布时间】: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 以便更容易看到)

结果: [Img]console.log results

如您所见,userTechsForSelect 数组一开始是空的,但后来不是。我认为 Select 组件在 userTechsForSelect 获取其值之前被渲染

【问题讨论】:

  • 你能添加userTechsForSelectallTechs的样子吗?
  • 您应该编辑此帖子以添加上下文,而不是发布答案。我之所以问是因为我很好奇userTechsForSelect[0] 中的对象的value 是否与allTechs 中的任何value 匹配。
  • 抱歉,我没有看到“编辑”按钮,我从现在开始编辑。

标签: reactjs react-hooks react-select


【解决方案1】:

我刚刚解决了!

正如我所怀疑的,组件在userTechsForSelect 有任何价值之前就被渲染了。所以我创建了一个function 来验证是否userTechsForSelect.length &gt; 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;

【讨论】:

  • 谢谢 - 我有同样的问题,这解决了我的问题
【解决方案2】:

由于您已将 isMulti 作为 true 传递,因此您的 defaultValue 应该是一个数组

defaultValue={[userTechsForSelect[0]]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 2013-04-13
    • 2016-10-23
    相关资源
    最近更新 更多