为什么React不更新DOM?

时间:2017-08-25 16:23:13

标签: javascript reactjs react-native

为什么React不为以下代码更新DOM?我希望当状态改变时突出显示的项目会改变,但这不会发生。

https://gist.github.com/davorb/abf505bac4f3f67f30bffffc539abf0a

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
  FlatList
} from 'react-native';

const food = [
  {
    key: 'Sushi'
  },
  {
    active: true,
    key: 'Burgare'
  },
  {
    key: 'Pizza'
  },
  {
    key: 'Pasta'
  }
];

const FoodList = (props) => {
  console.log(props.selected === food[0].key);
    return (
      <FlatList
        data={food}
        renderItem={({item}) =>
            <View style={styles.item}>
              <Text
                      style={item.key === props.selected ? styles.activeItem : styles.textItem}>
                      {item.key}
              </Text>
            </View>}
        />
    )
}

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.i = 0;
    this.state = {
      selected: food[this.i]
    };

    setInterval(() => {
      this.i = (this.i + 1) % food.length;
      this.setState(previousState => {
        return {
          selected: food[this.i]
        };
      });
    }, 1000);
  }

  renderFoodlist() {
    return (
        <FoodList selected={this.state.selected.key} />
    )
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>Shake your phone to open the developer menu.</Text>
        {this.renderFoodlist()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 22,
  },
  textItem: {
    fontSize: 24,
  },
  activeItem: {
    fontSize: 24,
    backgroundColor: 'red',
  },
});

1 个答案:

答案 0 :(得分:1)

来自https://facebook.github.io/react-native/docs/flatlist.html

  

通过将extraData = {this.state}传递给FlatList,我们确保FlatList   当state.selected更改时,它本身将重新呈现。没有设定   这个道具,FlatList不知道它需要重新渲染任何物品   因为它也是一个PureComponent而且道具比较不会   显示任何变化。

请参阅此示例,注意当您注释掉extraData时会发生什么(它不会更新)。

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
  FlatList,
  TouchableHighlight,
} from 'react-native';

const food = [
  {
    key: 'Sushi'
  },
  {
    key: 'Burgare'
  },
  {
    key: 'Pizza'
  },
  {
    key: 'Pasta'
  }
];

class FoodList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      selected: 0,
    };
  }

  _renderItem(item) {
    return (
      <TouchableHighlight onPress={() => this.setState({ selected: item.index })}>
        <View>
          <Text style={this.state.selected === item.index ? styles.activeItem : styles.textItem}>
            {item.index} {item.item.key}
          </Text>
        </View>
      </TouchableHighlight>
    );
  }

  render() {
    return (
      <View>
        <Text>{JSON.stringify(this.state)}</Text>
        <FlatList
          data={food}
          keyExtractor={(item) => item.key}
          renderItem={(item) => this._renderItem(item)}
          extraData={this.state}  // IMPORTANT!
        />
      </View>
    );
  }
}

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <FoodList />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 22,
  },
  textItem: {
    fontSize: 24,
  },
  activeItem: {
    fontSize: 24,
    backgroundColor: 'red',
  },
});