ReactJS将未闭合的元素推送到变量

时间:2017-03-16 18:34:40

标签: reactjs react-jsx

我有一个表单生成器,它根据JSON元素生成表单元素。因为在进程中,我们追加一个open元素,JSX会抛出一个错误。什么是实现这一目标的最好的反应方式?

示例JSON:

[
    {
        "name": "1900",
        "label": "Year 1900"
    },
    {
        "name": "",
        "label": "Group 2000",
        "type": "groupstart"
    },
    {
        "name": "2000",
        "label": "Year 2000",
        "select": true
    },
    {
        "name": "2001",
        "label": "Year 2002"
    },
    {
        "name": "2002",
        "label": "Year 2002"
    },
    {
        "name": "",
        "label": "",
        "type": "groupend"
    },
    {
        "name": "2100",
        "label": "Year 2100"
    }
]

预期输出

<select>
    <option value="1900">Year 1900</option>
    <optgroup label="Group 2000">
        <option value="2000" selected>Year 2000</option>
        <option value="2001">Year 2001</option>
    </optgroup>
    <option value="2100">Year 2100</option>
</select> 

到目前为止我的代码片段:

let fieldOptions = []
    field.options.selectOptions.map(function(entry){
      if (entry.type === 'groupstart') {
        fieldOptions.push(<optgroup label={entry.label}>)
      } else if (entry.type === 'groupend') {
        fieldOptions.push('</optgroup>');
      } else {
        fieldOptions.push(<option value={entry.name}>{entry.label}</option>)        
      }
    });
    results.push(
      <select
        name={field.name}
        ref={field.name}
        key={field.id}
        onChange={(e) => {field.onChange(e, field.entryType); }}
        onFocus={() => { focusFunction(field); }}
        value={field.value}>
          { fieldOptions }
      </select>
    );

1 个答案:

答案 0 :(得分:1)

是的,React(JSX)无法做到这一点。你必须做像

这样的事情
let fieldOptions = [];
let group;

for (let index = 0; index < field.options.selectOptions.length; index++) {
    let entry = field.options.selectOptions[index];

    if (!entry.type) {
        let option = <option value={ entry.name }>{ entry.label }</option>;
        if (group) group.push(option);
        else fieldOptions.push(option);
    } else if (entry.type === 'groupstart') {
        group = [];
        group.push(<option value={ entry.name }>{ entry.label }</option>);
    } else if (entry.type === 'groupend') {
        const groupStart = group[0];
        group.push(<option value={ entry.name }>{ entry.label }</option>);
        fieldOptions.push(<optgroup label={ groupStart.label }>{ group }</optgroup>);
        group = null;
    }
}

results.push(
    <select
        name={ field.name }
        ref={ field.name }
        key={ field.id }
        onChange={ (e) => { field.onChange(e, field.entryType); } }
        onFocus={ () => { focusFunction(field); } }
        value={ field.value }>
        { fieldOptions }
    </select>
);

为什么你的JSON会持平?您应该考虑修改JSON模式以支持嵌套元素。

更好的架构将是

[
    {
        "name": "...",
        "label": "..."
    }, 
    {
        "type": "group",
        "label": "...",
        "items": [
            {
                "name": "...",
                "label": "..."
            }
            ...
        ]
    }
]