fra*_*nky 5 javascript reactjs immutable.js
我无法弄清楚如何使用Immutable.js游标短路渲染React组件树的分支.
请看以下示例:
import React from 'react';
import Immutable from 'immutable';
import Cursor from 'immutable/contrib/cursor';
let data = Immutable.fromJS({
things: [
{title: '', key: 1},
{title: '', key: 2}
]
});
class Thing extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.thing.deref() !== nextProps.thing.deref();
}
handleChangeTitle(e) {
this.props.thing.set('title', e.target.value);
}
render() {
return <div>
<input value={this.props.thing.get('title')}
onChange={this.handleChangeTitle.bind(this)} />
</div>;
}
}
class Container extends React.Component {
render() {
const cursor = Cursor.from(this.props.data, 'things', newThings => {
data.set('things', newThings);
renderContainer();
});
const things = cursor.map(thing => (
<Thing thing={thing} key={thing.get('key')} />
));
return <div>
{things}
</div>;
}
}
const renderContainer = () => {
React.render(<Container data={data} />, document.getElementById('someDiv'));
};
Run Code Online (Sandbox Code Playgroud)
说我改变了第一个Thing头衔.只有第一个Thing将使用新标题呈现,第二个Thing将不会重新呈现由于
shouldComponentUpdate.但是,如果我更改第二个Thing标题,第一个Thing标题将返回到''第二个标题Thing仍然指向较旧版本的根数据.
我们更新每个渲染的游标,Container但由于shouldComponentUpdate也没有使用更新的根数据获取新游标而不渲染的游标.我可以看到保持游标最新的唯一方法是删除
此示例shouldComponentUpdate中的Thing组件.
有没有办法更改此示例以使用shouldComponentUpdate快速参照等式检查,但也保持游标更新?
或者,如果不可能,您是否可以概述一下如何使用游标+ React组件并仅渲染具有更新数据的组件?
我更新了您的代码,请参阅内联评论:
class Thing extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.thing.deref() !== nextProps.thing.deref();
}
handleChangeTitle(e) {
// trigger method on Container to handle update
this.props.onTitleChange(this.props.thing.get('key'), e.target.value);
}
render() {
return <div>
<input value={this.props.thing.get('title')}
onChange={this.handleChangeTitle.bind(this)} />
</div>;
}
}
class Container extends React.Component {
constructor() {
super();
this.initCursor();
}
initCursor() {
// store cursor as instance variable to get access from methods
this.cursor = Cursor.from(data, 'things', newThings => {
data = data.set('things', newThings);
// trigger re-render
this.forceUpdate();
});
}
render() {
const things = this.cursor.map(thing => (
<Thing thing={thing} key={thing.get('key')} onTitleChange={this.onTitleChange.bind(this)} />
));
return <div>
{things}
</div>;
}
onTitleChange(key, title){
// update cursor to store changed things
this.cursor = this.cursor.update(x => {
// update single thing
var thing = x.get(key - 1).set('title', title);
// return updated things
return x.set(key - 1,thing);
});
}
}
const renderContainer = () => {
React.render(<Container data={data} />, document.getElementById('someDiv'));
};
Run Code Online (Sandbox Code Playgroud)