从后代反应本机FlatList Rerender

时间:2018-06-27 11:52:25

标签: react-native

对不起,伙计们,我确实尝试过对以前的问题进行研究。

我在应用程序中将以下组件实现为屏幕:

class DivisionManagmementScreen extends Component {

    constructor(props) {
        super(props);

        this.state = {
            divisions: [],
            toggle: true
        };
    }

    async componentDidMount() {

        let programId = this.props.navigation.getParam("programId", 1);

        this.db = await open({name: "stats.db",createFromLocation: "~soccerstats.db"});

        const sql = "SELECT * FROM DIVISION where DIVISION_PROGRAM_ID = ? ORDER BY DIVISION_NAME";

        let result = await query(this.db, sql, [programId]); 

        this.setState({divisions: result.result});
    }

    async componentWillUnmount() {
        await close(this.db);
    }

    _renderItem = ({item}) => (
        <DivisionManagementRow divisionId={item.DIVISION_ID} divisionName={item.DIVISION_NAME} />
    );


    render() {
        return (
            <View style={styles.component}>
                <View style={styles.listArea}>
                    <FlatList 
                        data={this.state.divisions}
                        renderItem={this._renderItem}
                        keyExtractor={(item) => item.DIVISION_ID.toString() }
                        extraData={this.state.toggle}/>
                </View>
                <View style={styles.bottomButtonArea}>
                    <View style={styles.bottomButtonSection}>
                        <MenuNavigationButton label="Add Division" target="AddDivisionScreen" />
                    </View>
                </View>
            </View>
        );
    }
}

export default withNavigation(DivisionManagmementScreen);

请注意,我正在使用传递的this.state.toggle作为FlatList extraData参数的参数。

以下是FlatList呈现的数据行(负样式,原型等)的实现:

DivisionManagementRow类扩展了组件{

constructor(props) {
    super(props);

    this.state = {toggle: true};

}

_btnTeams = () => {

    // navigate to Team Management
}

_btnEditDivision = () => {
    this.props.navigation.navigate("EditDivisionScreen", {divisionId: this.props.divisionId});
}

_btnDeleteDivision = () => {

    console.log("Entered _btnDeleteDevision");
    Alert.alert(
        "Are you sure?",
        "This will delete all teams that are assigned to this division. Are you sure you want to do this?",
        [
            {text: "Cancel"},
            {text: "Ok", onPress: () => this._deleteDivision()}
        ]
    );
}

_deleteDivision = async () => {

    console.log("Entered _deleteDivision, divisionId: " + this.props.divisionId);
    const sql = "DELETE FROM DIVISION WHERE DIVISION_ID = ?";

    let divisionId = this.props.divisionId;
    let db = await open({name: "stats.db",createFromLocation: "~soccerstats.db"});
    let result = await execute(db, sql, [divisionId]);

    console.log("Rows affected: " + result.rowsAffected);

    await close(db);

    this.setState({toggle: !this.state.toggle});

}

render() {

    return (
        <View style={styles.component}>
            <Text>{this.props.divisionName}</Text>
            <View style={styles.buttonSection}>
            <TouchableOpacity style={styles.button}
                onPress={this._btnAddTeam}>
                <Text style={styles.buttonText}>Teams</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.button}
                onPress={this._btnEditDivision}>
                <Text style={styles.buttonText}>Edit</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.button}
                onPress={this._btnDeleteDivision}>
                <Text style={styles.buttonText}>Delete</Text>
            </TouchableOpacity>
            </View>
        </View>
    );
}

}

前两个“按钮”(TouchableOpacitys)可以正常工作,因为它们只是导航到不同的屏幕。但是,第三个“删除”没有屏幕。它显示警告以确认操作,然后在_deleteDivision()方法中运行删除代码。不幸的是,执行该方法不会强制重新呈现FlatList。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

由于从查询的数据数组中删除了一条记录,因此需要重新查询/查询项目并更新状态,以使FlatList显示新项目。为此,您可以执行以下步骤;

  1. 将查询功能从componentDidMount生命周期方法移至一个单独的函数,然后在componentDidMount中调用该函数
  2. 将属性传递到您的DivisionManagementRow。为该属性分配一个功能。
  3. 在您传递的该函数中重新运行查询功能。
  4. 成功删除项目后,请运行此功能。

示例 (为简单起见,删除了一些部分)

class DivisionManagmementScreen extends Component {
  componentDidMount() {
    this.db = await open({name: "stats.db",createFromLocation: "~soccerstats.db"});
    this.fetchItems()
  }
  async componentWillUnmount() {
    await close(this.db);
  }
  fetchItems = () => {
    let programId = this.props.navigation.getParam("programId", 1);
    const sql = "SELECT * FROM DIVISION where DIVISION_PROGRAM_ID = ? ORDER BY DIVISION_NAME";
    let result = await query(this.db, sql, [programId]); 
    this.setState({divisions: result.result});
  }
  _renderItem = ({item}) => (
    <DivisionManagementRow 
      divisionId={item.DIVISION_ID} 
      divisionName={item.DIVISION_NAME}
      onDelete={this.fetchItems}
    />
  )
  render() {
    return(
      <View style={styles.component}>
        <View style={styles.listArea}>
          <FlatList 
              data={this.state.divisions}
              renderItem={this._renderItem}
              keyExtractor={(item) => item.DIVISION_ID.toString() }
              extraData={this.state.toggle}/>
        </View>
        <View style={styles.bottomButtonArea}>
          <View style={styles.bottomButtonSection}>
              <MenuNavigationButton label="Add Division" target="AddDivisionScreen" />
          </View>
        </View>
      </View>
    )
  }
}

_deleteDivision = async () => {
  const sql = "DELETE FROM DIVISION WHERE DIVISION_ID = ?";
  let divisionId = this.props.divisionId;
  let db = await open({name: "stats.db",createFromLocation: "~soccerstats.db"});
  let result = await execute(db, sql, [divisionId]);
  await close(db);
  this.setState({toggle: !this.state.toggle}, () => {
    this.props.onDelete(); // running passed down function
                           // after state set   
  });
}