首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >JSX select元素似乎不能自动选择(实现'selected') on选项。我是不是遗漏了什么?

JSX select元素似乎不能自动选择(实现'selected') on选项。我是不是遗漏了什么?
EN

Stack Overflow用户
提问于 2021-11-03 23:11:18
回答 1查看 57关注 0票数 0

我有一个<select>标记,我用它来创建自己的自定义<SelectField>组件,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default function SelectField(props) {
  /* 
  PARAMS:
    - fieldname (String)
    - fieldID (String)
    - options (Array([Object, Object...]) [{"option_value": "option_name"}, ...])
    - init_value (String "option_value")
  */
  const generate_options = () => {
    // Function for handling SelectField options
    let element_list = [];
    element_list.push(
      <SelectOption key={0} option_value="" option_text="None" />
    );

    var count = 1;

    if (!Array.isArray(props.options)) {
      for (var [value, name] of Object.entries(props.options)) {
        element_list.push(
          <SelectOption key={count} option_value={value} option_text={name} />
        );
        count += 1;
      }
    } else {
      props.options.forEach((subject) => {
        element_list.push(subject.to_option());
      });
    }
    return element_list;
  };

  const nameToString = () => {
    // Converts props.fieldname into a properly formatted name
    if(props.fieldname.indexOf("_")){
      var full_field_name = `${props.fieldname.split("_").join(" ")}`;
      return `${full_field_name[0].toUpperCase() + full_field_name.slice(1)}`;
    };
    return `${props.fieldname[0].toUpperCase() + props.fieldname.slice(1)}`;
  };

  return (
    <div className="form-group">
      <label htmlFor={props.fieldname}>
        {nameToString()}:
      </label>
      <select
        name={`${props.fieldname}`}
        id={`${props.fieldID}`}
        className="countries"
        defaultValue={props?.init_value ? `${props.init_value}` : ""}
      >
        {generate_options()}
      </select>
    </div>
  );
}

(PS。不要介意className -它真的不应该相关。但谁知道像我这样的初学者。DS)。现在,我想使用该字段在我的web应用程序(由Django提供支持)中为Subjects创建一个<select>标记,并为其创建了一个如下所示的子组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function SubjectSelectField(props) {
  const [subjects, setSubjects] = useState([]);

  useEffect(() => {
    const getSubjects = async () => {
      let reqObj = new RequestHandler("/courses/subjects/");
      const data = await reqObj.sendRequest();
      setSubjects(
        data.map((item) => {
          return new Subject(item);
        })
      );
    };
    getSubjects();
  }, []);
  console.log({ subjects });

  return <SelectField options={subjects} {...props} />;
}

在使用此组件呈现页面时,我得到了以下console.logs:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "subjects": [
        {
            "id": 6,
            "name": "Art"
        },
        {
            "id": 4,
            "name": "Biology"
        },
        {
            "id": 5,
            "name": "Chemistry"
        },
        {
            "id": 3,
            "name": "Geography"
        },
        {
            "id": 2,
            "name": "Language"
        },
        {
            "id": 1,
            "name": "Mathmatics"
        },
        {
            "id": 7,
            "name": "Physics"
        },
        {
            "id": 8,
            "name": "Social Studies"
        }
    ]
}

作为参考,这是我的自定义Subject类(ES6):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export class Subject {
  constructor({ id, name }) {
    this.id = id;
    this.name = name;
  }
  to_option() {
    return (
      <SelectOption
        key={this.id}
        option_value={this.id}
        option_text={this.name}
      />
    );
  };
}

<SelectOption>组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function SelectOption(props) {
  return <option value={`${props.option_value}`} >{`${props.option_text}`}</option>;
}

因此,我期望的输出是<SelectField>自动将selected属性赋给具有<SelectField>init_value属性值的选项。我将<SelectField>用于另一种类型的字段,我称之为<CountrySelectField>,它工作得很好。我希望预先选择的国家是根据它的init_value正确选择的。

该组件如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function CountrySelectField(props) {
  return (
    <SelectField
      init_value={props?.student?.country ? `${props.student.country}` : ""}
      {...props}
    />
  );
}

正如我所提到的,如果我将一个值传递给这个组件的init_value属性,它就会像预期的那样执行,并使用设置了selected属性的正确选项进行呈现。

<SubjectSelectField>没有按照我期望的方式呈现--正确的<option>设置了selected属性。

为什么它不起作用?

编辑:

将Subject类更改为React功能组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function Subject(props){
  const id = props.subject.id;
  const name = props.subject.name;

  console.log(id, name, props.subject);
  if(props.option){
    return(
      <SelectOption
        key={id}
        option_value={id}
        option_text={name}
      />
    );
  }
  return(
    <h1>{name} - {id}</h1>
  );
}

为了让其他东西正常工作,我也改变了这些东西:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function SubjectSelectField(props) {
  // ...
  setSubjects(
        data.map((item) => {
          return <Subject subject={item} />;
        })
      );
  // ...

该选项仍不会被自动选择。我还有其他的字段,它们使用的大部分都是相同的逻辑(SelectField在其他地方也用得很好),但是我在这里显然搞乱了一些东西。

PS。如果你有时间进行语言监督,你肯定也有时间研究这个问题。“不是吗,”halfer?天啊..。DS.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-09 18:08:34

我松了一口气,因为我自己解决了这个问题,问题是我从来没有在SubjectSelecField上实现检查,以便仅在从服务器加载Subject时才呈现<select>字段。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function SubjectSelectField(props) {
  const [subjects, setSubjects] = useState([]);
  // Here I use 'loaded' as a check variable when rendering.
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    const getSubjects = async () => {
      let reqObj = new RequestHandler("/courses/subjects/");
      try{
        const data = await reqObj.sendRequest();
        setSubjects(
          data.map((item) => {
            return <Subject subject={item} />;
          })
        );
        // If the Subjects load properly, set 'loaded' to true.
        setLoaded(true);
      }
      catch(error){
        console.log(`Something went wrong when trying load Subjects from server!`);
        console.error(error);
        // Else we make sure its set to false.
        setLoaded(false);
      }
      
    };
    getSubjects();
  }, []);
  console.log({ subjects });

  // Here, before rendering, we check for the 'loaded' variable
  // to make sure the <select> tag doesn't try to load without
  // the <option> tags. Otherwise, the 'defaultValue' prop won't work.
  if(loaded) return <SelectField init_value={props.init_value} options={subjects} {...props} />;
  return <span>Loading Subject list...</span>;
}

至少感谢大家对它的研究:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69835505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文