【问题标题】:React, working with select component with objects反应,使用带有对象的选择组件
【发布时间】:2020-12-30 13:40:26
【问题描述】:

我是新手,我对材料 ui 的选择组件有疑问。

事情是这样的,我有一个用于创建和编辑用户的功能,这个用户是一个对象,它有主键和一些数据,在这个数据之间有一个与其他对象的关系,它是一个角色,所以在这种情况下,我使用 Select 组件来选择角色。

所以,我有我从后端带来的角色列表:

const [rolList, setRolList] = React.useState([]);

const searchRoles = async () => {
    try {
      setRolList(await api.post('/v1/roles/buscar', filtroRol));
    } catch (error) {
      snackbar.showMessage(error, "error");
    }
  }

还有一个formik里面的select组件:

              <Mui.Select 
                    label="Role"    
                    value={values.usuRolPk}
                    onChange={(opt) =>{handleChange(opt);
                    }}          
                    >
                      <Mui.MenuItem disabled key={0} value=''>
                        Select role
                      </Mui.MenuItem>
                    {rolList.map((e) => {
                        return <Mui.MenuItem key={e.rolPk} value={e.rolPk}>{e.rolName}</Mui.MenuItem>;
                    })}
                  </Mui.Select>

如您所见,对于 select 的值,我使用角色的 pk,因此当用户被持久化时,我必须在角色列表中搜索并将所选对象附加到用户对象并将其发送到后端。

类似这样(usuRolPk 是选择的值,usuRol 是与对象角色的关系):

const save = async (values) => {
    try {      
      
      if(values.usuRolPk==null){
        values.usrRole=null;
      }else{      
        values.usrRole=rolList.filter(element=>''+element.rolPk==values.usuRolPk)[0];
      }  
     ...

      if (values.usrPk == null) {
        await api.post('/v1/users', values);
      } else {
        await api.put('/v1/users/' + values.usrPk, values);
      }
      handleClose();
      snackbar.showMessage("GUARDADO_CORRECTO", "success")
    } catch (error) {
      snackbar.showMessage(error, 'error');
    }
    return;
  }

问题是,我想跳过必须在具有所选 Pk 的角色列表中搜索的最后一步。 有没有办法只使用对象作为选定值而不是 pk?我尝试只更改值以使整个对象像这样:

                  <Mui.Select 
                        label="role"    
                        value={values.usuRol}
                        onChange={(opt) =>{handleChange(opt);
                        }}          
                        >
                          <Mui.MenuItem disabled key={0} value=''>
                            Select role
                          </Mui.MenuItem>
                        {rolList.map((e) => {
                            return <Mui.MenuItem key={e.rolPk} value={e}>{e.rolName}</Mui.MenuItem>;
                        })}
                      </Mui.Select>

这仅在我创建一个新对象时有效,但是当我尝试编辑一个已经存在并且已经具有角色的对象时,当我将角色传递给选择时它说我用一个值初始化选择角色列表中不存在。

有没有办法做到这一点?

谢谢!

【问题讨论】:

  • 将其简化为明确的问题陈述和最小再现案例。也许其他人可以弄清楚你在这里追求什么,但我什至无法说出你的问题是什么。您有 ajax 和 formik 以及事件处理程序以及带有快餐栏的错误报告和和和...并且 任何 甚至与您的问题相关吗?这不是一个修辞问题,老实说我不能说。
  • 好吧,长话短说,我想用 select 组件选择整个对象,而不仅仅是对象的键
  • 将两个值置于 state 中:一个对象以 id 为键,一个当前选择的对象。在 select 上放置一个更改处理程序,该处理程序从 option.value 获取 id 并从第一个获取相应的对象,然后将当前选择的状态更新为该对象。
  • 似乎是个好主意,我会试试的,谢谢
  • 发布了一个基本的 POC 作为答案。

标签: javascript reactjs react-native material-ui


【解决方案1】:

在问题的 cmets 中的每个对话:

我只是为了方便而使用普通的选择和选项来执行此操作,但您可以很容易地将它们替换为它们的 mui 等效项:

import React, { useState, useEffect, useCallback } from 'react';

const SomeComponent = () => {
  const [list, setList] = useState({}); // { "1": someObjWithId1, etc }
  const [selected, setSelected] = useState();
  useEffect(() => {
    const getList = async () => {
      const resp = await fetch('/some/url'); // get object list from backend
      const data = await resp.json();
      setList(data);
    };

    if (!list.length) getList();
  }, []);

  const handler = useCallback((evt) => {
    setSelected(list[evt.target.value]);
  }, [list, setSelected]);

  return (
    <select onChange={handler}>
      {Object.entries(list).map(([id, obj]) => selected && id === selected.id
        ? <option selected key={id} value={id}>{obj.text}</option>
        : <option key={id} value={id}>{obj.text}</option>
      )}
    </select>
  );
};

一旦从后端传递了选项,该组件将呈现一个带有选项的选择元素。更改处理程序将使用选定的整个对象(由 id/值键控)来更新状态。在现实生活中,您可能会在父表单组件中拥有状态,并通过 props 将其与 setter 一起传递,但您明白了。

【讨论】:

    猜你喜欢
    • 2021-12-13
    • 1970-01-01
    • 2022-09-23
    • 2018-04-27
    • 2021-08-09
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    相关资源
    最近更新 更多