我有一个列表,其中包含首先加载30个项目的项目,如果用户点击"全部加载",则会显示其余项目:
+---------------------------------------------------------+
| |
| List |
| |
| |
| |
+---------------------------------------------------------+
| Load All Button |
+---------------------------------------------------------+
当列表很大(超过1K项)时,"加载全部"步骤需要一些时间,同时DOM被卡住而没有响应。
利用React的生命周期事件的正确方法是什么,以便点击按钮后它将变为加载微调器,当列表完全呈现并准备就绪后它会改回来?
我尝试将两个部分(列表和按钮)分成两个组件,然后将它们包装在一个包含" loading"的父组件中。然后更改列表componentDidUpdate
功能中的状态,但它没有工作
答案 0 :(得分:8)
React中的渲染是同步的,这意味着没有任何东西可以与它一起运行。
您可以逐步呈现列表,因为用户的屏幕可能无法一次显示超过100个项目。
另外,请注意,在开发构建中渲染数千个项目比在React的生成构建中慢得多。
编辑:另一种选择是首先渲染加载器,然后在下一帧渲染列表项。将显示加载程序,直到列表项完成呈现。
React.createClass({
getInitialState: function() {
return {
loading: false,
showAll: false,
};
},
_showAll: function() {
this.setState({ showAll: true, loading: true }, function() {
// Using setTimeout here ensures that the component will wait until
// the next frame before trying to render again.
this.setTimeout(function() {
this.setState({ loading: false });
}.bind(this), 1000 / 60);
});
},
render: function() {
var amount = (this.state.showAll && !this.state.loading) ? 100000 : 3;
return (
<div>
<button onClick={this._showAll}>
{this.state.loading ? 'Loading...' : 'Show all'}
</button>
{items.slice(0, amount).map(renderItem)}
</div>
);
},
});
答案 1 :(得分:0)
这是一个简单的类,其中包含更新的React 16示例(为清晰起见,使用内联注释):
class People extends Component {
state = {
rows: [],
loaded: false
}
/* lifecycle hook - keeping mind we are manipulating the DOM */
/* within the component so we need to know the component/dom is ready */
componentDidMount(){
let self = this;
/* returns a fetch() call stored in context passed down */
/* through a higher order component */
this.props.context.getPeople()
.then(json => { self.setState({rows:json.rows, loaded: true}); })
/* Notice that loaded is set to true in the state object */
}
loading = () => (
<div className={this.state.loaded?'ajax-loaded':'ajax-loading'}>LOADING</div>
/* The class ajax-loaded -- you guessed it, hides the div */
/* The thing to always keep in mind -- when state changes, things happen! */
);
render() {
return (
<div>
{this.loading()}
{this.state.rows.map(row => ( <div>{row.first} {row.last}</div>) )}
{/* Again, when state changes, things happen! */}
</div>
)
}
}