使用嵌套的不可变记录更新状态

时间:2019-05-15 21:35:25

标签: reactjs immutable.js

我有一个Editor的Immutable.js记录,该记录具有嵌套的内容和选择记录。

因此,每当选择更改时,我都会获得选择的起点和终点,然后使用新的选择更新状态。

class SelectionStateRecord extends Immutable.Record({
        anchor: 0,
        focus: 0,
    }
) {
    // extra features
}

class EditorRecord extends Immutable.Record({
        key: uuid.v4(),
        ContentState: new ContentStateRecord(),
        SelectionState: new SelectionStateRecord(),
    }
) {
    // extra features
}

export default class TextEditor extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            EditorState: new EditorRecord()
            ...
        }
    }

    _onSelectionChange = e => {
        const {start, end} = e.nativeEvent.selection
        const newEditorState = this.state.EditorState.SelectionState.merge({
            focus: start,
            anchor: end,
        })
        this.setState({EditorState: newEditorState})
    }

    render() {
        ...
    }
}

但是,我收到此错误,我想我不能只为嵌套记录设置新值:

  

未定义不是对象(正在评估'_this.state.EditorState.SelectionState.merge')

但是,这可行:

    _onSelectionChange = e => {
        const {start, end} = e.nativeEvent.selection
        const newEditorState = this.state.EditorState.merge({
            key: uuid.v4(),
            ContentState: this.state.EditorState.ContentState,
            SelectionState: this.state.EditorState.SelectionState.merge({
                focus: start,
                anchor: end,
            }),
        })
        this.setState({EditorState: newEditorState}, () => {
            console.log('start', this.state.EditorState.SelectionState.start())
        })
    }

我只是不确定这是否是更新状态的正确方法,并且混淆了如何为单个嵌套的不可变记录设置/更新值以避免性能损失。

1 个答案:

答案 0 :(得分:0)

您可以只使用updateIn()吗? docs

例如

_onSelectionChange = e => {
        const {start, end} = e.nativeEvent.selection
        const newEditorState = this.state
          .updateIn(
            ['EditorState', 'SelectionState'],
            new SelectionStateRecord(), // default value (optional)
            ss => ss.set('focus', start).set('anchor', end)
          )
        )

        this.setState({EditorState: newEditorState}, () => {
            console.log('start', this.state.EditorState.SelectionState.start())
        })
    }