React setState/Flux-是否总是触发重新渲染? [英] React setState / Flux - Does it always trigger a re-render?

查看:142
本文介绍了React setState/Flux-是否总是触发重新渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我一直在与React Native一起玩,直到达到对所有组件之间共享状态的开始的兴趣,我开始对更妥善地管理状态感兴趣.

I've been playing around with React Native lately and I reached a point where I became interested in managing my state more properly, as a start achieving a shared state between all the components.

答案当然是助焊剂.在继续使用一些更高级的解决方案(例如Redux,Alt,MobX)之前,我认为我应该首先借助一个小工具(即Flux调度程序)来了解原始结构本身.

The answer of course is Flux. Before moving forward with some more advanced solutions (e.g. Redux, Alt, MobX) I thought I should start with understanding the raw structure itself, with the help of one small tool, that is the Flux dispatcher.

import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

import EventEmitter from 'EventEmitter';
import { Dispatcher } from 'flux';

class Store extends EventEmitter {
  list = [];

  actions = {
    add: title => dispatcher.dispatch({ type: 'add', payload: { title } })
  };

  handle = ({ type, payload }) => {
    switch(type) {
    case 'add': this.add(payload.title); break;
    }
  };

  add(title) {
    this.list.push(title);
    this.emit('change');
  }
}

const store = new Store(), dispatcher = new Dispatcher();

dispatcher.register(store.handle);

class App extends Component {
  state = { list: store.list };

  componentWillMount() {
    this.listener = store.addListener('change', () => this.setState({ list: store.list }));
  }

  componentDidMount() {
    setInterval(() => store.actions.add(new Date().getTime()), 1000);
  }

  componentWillUnmount() { this.listener.remove(); }

  render() {
    return (
      <View style={{ marginTop: 20 }}>
        <Text>{JSON.stringify(this.state.list)}</Text>
      </View>
    );
  }
}

AppRegistry.registerComponent('straightforwardFlux', () => App);

请注意,在视图层中,我们有{JSON.stringify(this.state.data)},自然地,当商店更新时,由于视图已链接至状态,因此视图将被重新渲染.

Notice in the view layer, we have {JSON.stringify(this.state.data)}, naturally when the store is updated the view will be re-rendered since it is linked to the state.

更改为{JSON.stringify(store.data)}时,视图也会重新渲染!这不会发生,因为只有在状态变化直接影响视图时才更新视图,在这种情况下,视图中不会呈现任何状态.我在这里想念什么吗?为什么我们会遇到这种行为?

When changing to {JSON.stringify(store.data)} the view is also re-rendered! this shouldn't happen because the view should only update when there is a change in the state that affect the view directly, in this case there is no state rendered in the view whatsoever. Am I missing something here? why would we encounter this behaviour?

这引起了另一个问题,是否在每次状态改变时都调用render()?即使它不影响视图层的外观?我研究了这个问题,得到了两个不同的答案,一个回答是,默认情况下componentShouldUpdate()返回true,这意味着需要在此处进行一些更改(如果这样,如何进行?),而另一个则完全没有. ,它不会随每个setState()更新.

This leads to another question, does render() get called every time there is a state change? even if it doesn't affect the way the view layer looks? I've looked into this and I got two different answers, one says yes and that componentShouldUpdate() returns true by default, meaning that some changes need to be made here (if so, how?), and the other one was simply no, it doesn't update with each setState().

总体而言,此实现是否正确?

Overall, is this implementation correct?

推荐答案

每个

setState()将始终触发重新渲染,除非在shouldComponentUpdate()中实现了条件渲染逻辑.如果正在使用可变对象,并且逻辑不能在shouldComponentUpdate()中实现,则仅当新状态不同于先前状态时调用setState()才能避免不必要的重新渲染.

setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate(). If mutable objects are being used and the logic cannot be implemented in shouldComponentUpdate(), calling setState() only when the new state differs from the previous state will avoid unnecessary re-renders.

tl; dr; .React不会分析您的视图以明确查看其所依赖的状态,这取决于您使用shouldComponentUpdate()进行优化.

tl;dr; React isn't analyzing your view to see explicitly what state it is depending on, that is up to you to optimize with shouldComponentUpdate().

shouldComponentUpdate(nextProps, nextState) {
  // check if your view's attributes changes
  let check1 = nextState.foo != this.state.foo
  let check2 = nextState.bar != this.state.bar

  // if return is true, the component will rerender
  return check1 || check2
}

这篇关于React setState/Flux-是否总是触发重新渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆