将 React 的 shouldComponentUpdate 与 Immutable.js 游标一起使用
Using React's shouldComponentUpdate with Immutable.js cursors
我无法弄清楚如何短路渲染分支
使用 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'));
};
假设我更改了第一个 Thing
的标题。只有第一个 Thing
会呈现
新标题和第二个 Thing
不会 re-render 由于
shouldComponentUpdate
。但是,如果我更改第二个 Thing
的标题,
第一个 Thing
的标题将返回到 ''
,因为第二个 Thing
的光标
仍然指向旧版本的根数据。
我们在 Container
的每个渲染器上更新光标,但不更新的那些
由于 shouldComponentUpdate
而渲染也没有得到更新后的新光标
根数据。我能看到使游标保持最新的唯一方法是删除
本例中 Thing
组件中的 shouldComponentUpdate
。
有没有办法将此示例更改为使用 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'));
};
我无法弄清楚如何短路渲染分支 使用 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'));
};
假设我更改了第一个 Thing
的标题。只有第一个 Thing
会呈现
新标题和第二个 Thing
不会 re-render 由于
shouldComponentUpdate
。但是,如果我更改第二个 Thing
的标题,
第一个 Thing
的标题将返回到 ''
,因为第二个 Thing
的光标
仍然指向旧版本的根数据。
我们在 Container
的每个渲染器上更新光标,但不更新的那些
由于 shouldComponentUpdate
而渲染也没有得到更新后的新光标
根数据。我能看到使游标保持最新的唯一方法是删除
本例中 Thing
组件中的 shouldComponentUpdate
。
有没有办法将此示例更改为使用 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'));
};