【问题标题】:How to properly render jsx-like html inside of javascript如何在 javascript 中正确呈现类似 jsx 的 html
【发布时间】:2019-03-31 15:53:50
【问题描述】:

我有一个反应组件,它根据状态用另一个组件呈现一些块。如何在 JS 中同时渲染类似 HTML 的 JSX 和组件?

class Feedback extends Component {
constructor(props) {
    super(props);
    this.state = {
        storeInputShow: true
    };
}
render() {
    return (
        <div>
            { this.state.storeInputShow ?
                <div className="form_field" style={{ marginBottom: '4px' }}>
                    <Text textTag="div">
                        Select shop
                    </Text>
                </div>
                <Autocomplete
                    items={this.state.storeList}
                    shouldItemRender={(item, value) => item.label && item.label.toLowerCase().indexOf(value.toLowerCase()) > -1}
                    getItemValue={item => item.label}
                    renderItem={(item, highlighted) =>
                        <div
                            key={item.id}
                            style={{ backgroundColor: highlighted ? '#eee' : '#ffffff', ...selectItemStyle }}
                        >
                            {item.label}
                        </div>
                    }
                    value={store}
                    onChange={e => this.setState({ store: e.target.value, storeId: e.target.id })}
                    onSelect={(store,storeCard) => this.setState({ store, storeId: storeCard.id })}
                    inputPlaceholder="Shop"
                    wrapperStyle={selectWrapperStyle}
                    menuStyle={selectMenuStyle}
                />
                : null
            }
        </div>
    );
}

现在错误如下:

SyntaxError: 相邻的 JSX 元素必须包含在封闭标记中

&lt;Autocomplete 标记处。

【问题讨论】:

    标签: javascript reactjs jsx


    【解决方案1】:

    错误是不言自明的,您应该将两个组件包装在一个中以使您的条件工作。

    <div>
        <div className="form_field" style... />
        <Autocomplete items={this.state.storeList} should... />
    </div>
    

    您可以使用React.Fragment 代替&lt;div /&gt;

    奖励:您可以使用以下语法删除结尾 null 大小写

    <div>
        { this.state.storeInputshow && <YourComponents /> }
    </div>
    

    这样你只会在 storeInputShow 可用的状态下渲染,而不需要返回 null 。

    【讨论】:

    • 我假设您使用&lt;&gt; 的一些插件来转换为&lt;React.Fragment&gt;。为了让大多数编辑器和转译器设置都能正常工作,最好使用&lt;React.Fragment&gt; 标记来展示您的示例。
    • @Keith 好点,只需将其更新为&lt;div /&gt;,这样就不会混淆
    • 是的,好主意。对于阅读本文的人来说,&lt;React.Fragment&gt; 的优势在于它不会创建额外的 DOM 元素,如果 DOM 排序对 CSS 等很重要,这可能很重要。
    • @AlexSanchez 谢谢,它工作正常。你的额外奖金也很方便
    【解决方案2】:

    您不能将 if 放入 return,但您可以放入一个变量。

    class Feedback extends Component {
    constructor(props) {
        super(props);
        this.state = {
            storeInputShow: true
        };
    }
    render() {
    
        let form;
    
        if (this.state.storeInputShow)
            form = <div className="form_field" style={{ marginBottom: '4px' }}>
                        <Text textTag="div">
                            Select shop
                        </Text>
                    </div>
                    <Autocomplete
                        items={this.state.storeList}
                        shouldItemRender={(item, value) => item.label && item.label.toLowerCase().indexOf(value.toLowerCase()) > -1}
                        getItemValue={item => item.label}
                        renderItem={(item, highlighted) =>
                            <div
                                key={item.id}
                                style={{ backgroundColor: highlighted ? '#eee' : '#ffffff', ...selectItemStyle }}
                            >
                                {item.label}
                            </div>
                        }
                        value={store}
                        onChange={e => this.setState({ store: e.target.value, storeId: e.target.id })}
                        onSelect={(store,storeCard) => this.setState({ store, storeId: storeCard.id })}
                        inputPlaceholder="Shop"
                        wrapperStyle={selectWrapperStyle}
                        menuStyle={selectMenuStyle}
                    />;
    
    
        return (
            <div>{ form }</div>
        );
    

    【讨论】:

    • 这只会给你同样的错误,.. 像 Alex 所说的那样使用 React.Fragment 是正确的答案。
    • 在没有数据突变的情况下处理问题总是更好,但感谢您的评论
    【解决方案3】:

    您的代码中的问题是,在 if 条件中,对于 true 情况,您将返回两个元素 (,),但在 JSX 中,它期望每个返回都是一个元素(可以有任意数量的子元素)。因此,只需使用包装器将您的元素包装在 if 条件中即可。

    class Feedback extends Component {
    constructor(props) {
        super(props);
        this.state = {
            storeInputShow: true
        };
    }
    render() {
        return (
            <div>
                { this.state.storeInputShow ?
                    <div>
                    <div className="form_field" style={{ marginBottom: '4px' }}>
                        <Text textTag="div">
                            Select shop
                        </Text>
                    </div>
                    <Autocomplete
                        items={this.state.storeList}
                        shouldItemRender={(item, value) => item.label && item.label.toLowerCase().indexOf(value.toLowerCase()) > -1}
                        getItemValue={item => item.label}
                        renderItem={(item, highlighted) =>
                            <div
                                key={item.id}
                                style={{ backgroundColor: highlighted ? '#eee' : '#ffffff', ...selectItemStyle }}
                            >
                                {item.label}
                            </div>
                        }
                        value={store}
                        onChange={e => this.setState({ store: e.target.value, storeId: e.target.id })}
                        onSelect={(store,storeCard) => this.setState({ store, storeId: storeCard.id })}
                        inputPlaceholder="Shop"
                        wrapperStyle={selectWrapperStyle}
                        menuStyle={selectMenuStyle}
                    />
                    </div>
                    : null
                }
            </div>
        );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2012-03-05
      相关资源
      最近更新 更多