JSX 选择元素似乎不会在选项上自动选择(实现"已选择")。我错过了什么吗?



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

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>
);
}

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

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.log:

{
"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(:

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>组件:

export function SelectOption(props) {
return <option value={`${props.option_value}`} >{`${props.option_text}`}</option>;
}

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

这个组件看起来像这样:

export function CountrySelectField(props) {
return (
<SelectField
init_value={props?.student?.country ? `${props.student.country}` : ""}
{...props}
/>
);
}

正如我所提到的,如果我将一个值传递给这个组件的init_value道具,它将按预期执行,并使用设置了selected属性的正确选项进行渲染。

<SubjectSelectField>并没有按照我期望的方式呈现——正确的<option>具有selected属性集。

为什么它不起作用?

编辑:

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

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>
);
}

为了让其他东西发挥作用,我也改变了这些东西:

export function SubjectSelectField(props) {
// ...
setSubjects(
data.map((item) => {
return <Subject subject={item} />;
})
);
// ...

该选项仍然不会自动选择。。我有其他字段使用的逻辑基本相同(SelectField在其他地方也使用,并且有效(,但我显然在这里搞砸了一些东西。

PS。如果你有时间和警察谈话,你肯定也有时间研究这个问题。不是吗,"halfer?"?天啊。。DS.

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

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>;
}

感谢人们尝试调查它,至少:(

最新更新