如何使listview中的动态数据源做出本机反应?

时间:2017-05-16 02:12:52

标签: reactjs react-native

我不知道我的代码发生了什么。我正在尝试创建一个Todo列表。我正在使用listview。我有两个组件Todo和AddTodo。

主要成分

import React, { Component } from 'react';
import { View, Text, TextInput, StyleSheet, ListView } from 'react-native';
import * as moment from 'moment';
import TodoList from '../compoents/TodoList';
import {TodoModel, ITodo} from '../models/TodoModel';

interface TodoProps{
    todo: TodoModel;
    ter:string;
}
interface TodoState{
    dataSource: any;
    myTodo: Array<ITodo>;
}


export default class Todo extends React.Component <TodoProps,TodoState>{

    constructor(props:TodoProps) {
        super(props);

        const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => true});
        this.state = {
            dataSource: ds,
            myTodo: []
        };

    }

    componentWillMount = () => {
        console.log(this.state.myTodo);
        let data = {
            title: this.props.ter
        };

        if (this.props.ter) {
          this.state.myTodo.push(data);
        }

        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(this.state.myTodo),
            myTodo: this.state.myTodo
        });
    }

    render() {

        return (
            <View style={{marginTop: 60}}>
                <ListView enableEmptySections={true} dataSource={this.state.dataSource} renderRow={(rowData) => <TodoList data={rowData} /> } />
            </View>
        )
    }
}

这将查看我从表单

添加的待办事项列表

AddTodo组件

import * as React from "react";
import { Alert, View, Text, StyleSheet, TextInput, TouchableOpacity } from 'react-native';
import {TodoModel} from '../models/TodoModel';
import { Actions} from 'react-native-router-flux';
interface TodoState{
    todoText?: string;
}
interface TodoProps{
    text: string;
}
export default class AddTodo extends React.Component <TodoProps,TodoState> {

    constructor(props:TodoProps){
        super(props);
        this.state = {
            todoText:" "
        };
    }

    handleSubmit = () => {

        Actions.todo({ter: this.state.todoText});
    }

    render() {
        return (
            <View style={{margin: 128, marginLeft: 15, marginRight:15}}>
                <Text>ADD</Text>
                <TextInput autoCorrect={false} style={styles.input} placeholder='Todo' onChangeText={(text) => this.setState({todoText:text})} value={this.state.todoText} />
                <TouchableOpacity onPress={this.handleSubmit.bind(this)}>
                    <Text style={styles.button}>Submit</Text>
                </TouchableOpacity>
            </View>
        )
    }
}


const styles = StyleSheet.create({
    button: {
        backgroundColor: '#ccc',
        color: 'white',
        height: 40,
        lineHeight: 30,
        marginTop: 10,
        textAlign: 'center',
        alignSelf: 'stretch',
        borderRadius: 5,
        justifyContent: 'center',
        alignItems: 'center',
    },
    container: {

    },
    input: {
        borderColor: '#ededed',
        borderRadius: 5,
        borderWidth: 1,
        height: 37,
        alignSelf: 'stretch',
    }
})

这里的问题。当我添加一个待办事项的时候。我成功添加到myTodo数组,但是当我添加第二个待办事项时。它删除了第一个待办事项,并显示第二个待办事项。它不会推送并添加到数组中。为什么会这样?但如果你有如何做的教程。研究它会更好。我很想学习反应原生。

更新

export default class App extends React.Component<Props, State> {
    render() {
        return (
            <Router>
                <Scene key="root">
                        <Scene key="todo" component={Todo} title="Todo" initial={true}  onRight={() => Actions.addTodo({text: 'Hello World!'})}
                               rightTitle="Add"/>
                        <Scene key="addTodo" component={AddTodo} title="Add Todo" backTitle="Cancel" />
                </Scene>
            </Router>
        );
    }
}

2 个答案:

答案 0 :(得分:0)

试试我的代码,希望它可以帮到你。 你的推动&#34;将直接改变状态,这可能会导致容易出错的代码,即使你是'#34;重置&#34;之后的状态再次

您可以在此处找到更多信息:Correct modification of state arrays in ReactJS

编辑:

  • 重写handleSubmit函数

&#13;
&#13;
handleSubmit = () => {
        Actions.pop({refresh : 
          {ter:   this.state.todoText}
        });
    }
&#13;
&#13;
&#13;

  • 将componentWillMount更改为componentWillReceiveProps

&#13;
&#13;
    componentWillReceiveProps = (nextProps) => {
        console.log(this.state.myTodo);
        let data = {
            title: nextProps.ter
        };
        let todoList = this.state.myTodo
        

        if (nextProps.ter) {
          todoList.push(data);
        }

        this.setState({
            myTodo: todoList
        });
    }
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以看到我对非常类似问题的回答:

React Native: Child ListView will not update after element in parent is changed

事实上,在你的情况下,你可能只是这样做:

const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => true});

export default class Todo extends React.Component <TodoProps,TodoState>{

    constructor(props:TodoProps) {
        super(props);   
        this.state = {
            dataSource: ds.cloneWithRows([]), // or put your initial data here
            myTodo: []
        };
    }

然后,每次您要更新列表,只需使用ds.cloneWithRows(NEW_DATA)

componentWillMount() {
    // ...

    this.setState({
        dataSource: ds.cloneWithRows(this.state.myTodo),
        myTodo: this.state.myTodo
    });
} 

还有一件事,对于组件生命周期中的react默认函数,它们会自动绑定,因此不需要使用componentWillMount = () => {},只需使用componentWillMount()

这就是你应该做的,如果错误仍然发生,请在这里显示,然后我们可以一起解决,谢谢