输入第一个字符后输入失去焦点,即使指定了键也是如此

时间:2015-03-25 18:06:32

标签: reactjs

我正在渲染一个字符串数组作为文本输入。渲染时,我渲染一个额外的输入,它会更新一个超过数组末尾的索引。问题是在输入第一个字符后,首次渲染新输入时,当前输入失去焦点。 (Fiddle

这些项目有一个关键道具,包括超出阵列末尾的一个额外项目。我应该提交错误报告,还是我在这里缺少关于表单输入如何工作的东西?

let MiniList = React.createClass({
    getInitialState() {
        return {
            items: []
        };
    },

    update( index, value ) {
        let items = this.state.items;
        items[ index ] = value;
        this.setState({ items: items });
    },

    renderItem( value, index ) {
        return (
            <div key={ index }>
                { index }
                <input type="text"
                    value={ value }
                    onChange={ event => this.update( index, event.target.value )}/>
            </div>
        );
    },

    render() {
        return (
            <div>
                { this.state.items.map( this.renderItem )}
                { this.renderItem( null, this.state.items.length )}
            </div>
        );
    }
});

React.render( <MiniList />, document.body );

1 个答案:

答案 0 :(得分:3)

<div>
    { this.state.items.map( this.renderItem )}
    { this.renderItem( null, this.state.items.length )}
</div>

编译到

React.createElement("div", null,
    this.state.items.map( this.renderItem ),
    this.renderItem( null, this.state.items.length )
)

this.state.items.map( this.renderItem )中每个元素的键将以子列表中的数组索引作为前缀(在您的情况下为0)。这使得this.state.items.map( this.renderItem )中的任何元素与this.renderItem( null, this.state.items.length )返回的元素之间的协调变得不可能,因为它们不会共享相同的密钥。因此,当您向this.state.items添加新项目时,将卸载最后一个输入并在其位置安装新输入,这可以解释失去焦点。

要解决此问题,请确保所有商品元素都在同一个数组中。

<div>
    {
        this.state.items
            .map( this.renderItem )
            .concat( [this.renderItem( null, this.state.items.length )] )
    }
</div>

或只是

<div>
    { this.state.items.concat([null]).map( this.renderItem ) }
</div>