状态更新后组件未更新

时间:2020-08-02 06:10:37

标签: reactjs

以下代码不会更新我的组件。

使用另一个功能更新状态。所以我认为该组件也会更新。

整个班级在这里。

class QuestionList extends Component
{
    constructor(props)
    {
        super(props);
        this.state = {
            questions : []          
        }
        this.childHandler = this.childHandler.bind(this);
    }

    updateData()
    {
        const get = '/application/questions/'
        api.get(get)
            .then(response => {
                console.log(response);
                this.setState({questions : response.data});
            })
            .catch(err => console.log(err));
    }
    componentDidMount(){
        var tempArray = [];
        const get = '/application/questions/'
        api.get(get)
            .then(response => {
                console.log(response);
                this.setState({questions : response.data});
            })
            .catch(err => console.log(err));
    }

    childHandler( update )
    {
        const {questions} = this.state;
        let tempQs = questions;
        const length = questions.length;
        var temp = [];
        var temp1 = [];

        console.log ( tempQs );
        for(var i = 0; i < length; i++)
        {
            if(questions[i].q_id == update[1])//find New
            {
                temp = [questions[i].q_id,questions[i].question];
                for(var x = 0; x < length; x++)//find old
                {
                    
                    if(questions[x].q_id == update[0] && questions[x].q_id != questions[i].q_id ) 
                    {
                        temp1 = [questions[x].q_id,questions[x].question];
                        break;
                    }
                }
                break;
                
             
            }
        }       
        tempQs[temp[0]-1].question = temp1[1];
        tempQs[temp1[0]-1].question = temp[1];
        this.setState({questions : tempQs},console.log(questions));
    }

    render()
    {
        var { questions } = this.state;
        console.log(questions);
        var qs;
        qs = questions.map(val => {
            return(
                <QuestionCards q_id={val.q_id} max={questions.length} action={this.childHandler}>{val.question}</QuestionCards>
            )
        });

        return(
            <Table hover>
                <tbody>
                        <tr className="title">
                            <th>Id</th>
                            <th>Question</th>
                            <td colspan="3" ><Button color="primary">Add Question</Button></td>
                        </tr>
                    {qs}
                </tbody>
            </Table>
        );
    }
}

这是卡片部分

class QuestionCards extends Component
{
    constructor ( props )
    {
        super(props)
            this.state = {
                fireModal : false,
                modal : false,
                q_id : this.props.q_id,
                question : this.props.children,
                max : this.props.max
        }
        this.handleClick = this.handleClick.bind(this);
        this.handleModal = this.handleModal.bind(this);
        this.triggerModal = this.triggerModal.bind(this);
        this.moveUp = this.moveUp.bind(this);
        this.moveDown = this.moveDown.bind(this);
    }
   
    triggerModal ( trig )
    {
        const {q_id} = this.state;
        if (trig)
            return (
                <QListModal q_id={q_id} trigger={trig} action={this.childHandler}/>
            );
    }

    handleModal ( val )
    {
        const { fireModal } = this.state;
        console.log('fireModel: ' + fireModal)
        if( !fireModal )
        {
            this.setState({
                mTarget : val,
                fireModal : true   ,
                update : []
            });
        }
        else
        {
            this.setState({fireModal:false})
        }
        
    }

    moveUp ()
    {
        var tempArray = [];
        const { q_id } = this.state;
        const dir = 'up';
        const get = '/application/move/' + q_id +'/'+ dir;
        api.get(get).then(res => {
            console.log(res);
            this.setState({
                update : [res.data.newId,res.data.oldId]
            })
            return this.props.action(this.state.update);
        });
        //return this.props.action(this.state.update);
    }

    moveDown ()
    {
        var tempArray = [];
        const { q_id } = this.state;
        const dir = 'down';
        const get = '/application/move/' + q_id +'/'+ dir;
        api.get(get).then(res => {
            this.setState({
                update : [res.data.newId,res.data.oldId]})
            return this.props.action(this.state.update);
        });
        //return this.props.action();
    }

    render()
    {
        const {
            fireModal,
            q_id,
            question,
            max,
            update
        } = this.state

        let ButtonUp;
        let ButtonDown;
        if( q_id <= 1)
        {
            ButtonUp = <td></td>
        }
        else
        {
            ButtonUp = <td><Button id={q_id} onClick={this.moveUp}>▲</Button></td>
        }
        if( q_id == max)
        {
            ButtonDown = <td></td>
        }
        else
        {
            ButtonDown = <td><Button id={q_id} onClick={this.moveDown}>▼</Button></td>
        }
        return(
            <tr>
                <th>{q_id}</th>
                <td>{question}</td>
                <td><Button onClick={this.handleModal}>Edit</Button></td>
                {ButtonUp}
                {ButtonDown}
                {this.triggerModal(fireModal)}
            </tr>
            

        )
    }
}
    render()
    {
        var { questions } = this.state;

        var qs = questions.map(val => {
            return(
                <QuestionCards q_id={val.q_id} max={questions.length} action={this.childHandler}>{val.question}</QuestionCards>
            )
        });

        return(
            <Table hover>
                <tbody>
                    {qs}
                </tbody>
            </Table>
        );
    }
}

应用程序尝试执行的操作是每次按下向上或向下箭头。它会在页面上对其进行更新。

由于某种原因,在更新状态后,它不会更新输出本身。

虽然当我console.log状态时它会自动更新。

这是我第一个仍在学习React / Javascript的独立项目。

您可以看到状态正确更新。但只是不重新渲染任何东西。 react-dev-tools中的事件探查器工具不会输出任何呈现的内容。可能是因为父组件吗?

解决方案 我的问题是问题卡的构造函数。

 super(props)
            this.state = {
                fireModal : false,
                modal : false,
                q_id : this.props.q_id,
                question : this.props.children, // This line in particular
                max : this.props.max
        }

我没有使用新的信息更新状态。 所以我只将this.props.children的值分配给呈现函数中的常量

这是QuestionCards

的更新渲染
    render()
    {
        const {
            fireModal,
            q_id,
            max
        } = this.state

        const question = this.props.children;
        let ButtonUp;
        let ButtonDown;
        if( q_id <= 1)
        {
            ButtonUp = <td></td>
        }
        else
        {
            ButtonUp = <td><Button id={q_id} onClick={this.moveUp}>▲</Button></td>
        }
        if( q_id == max)
        {
            ButtonDown = <td></td>
        }
        else
        {
            ButtonDown = <td><Button id={q_id} onClick={this.moveDown}>▼</Button></td>
        }
        return(
            <tr>
                <th>{q_id}</th>
                <td>{question}</td>
                <td><Button onClick={this.handleModal}>Edit</Button></td>
                {ButtonUp}
                {ButtonDown}
                {this.triggerModal(fireModal)}
            </tr>
            

        )
    }

还删除了控制台日志以整理帖子!

谢谢大家帮助我解决问题!

1 个答案:

答案 0 :(得分:2)

问题

看起来像cardHandler中的状态突变

childHandler( update ) {
    const {questions} = this.state;
    let tempQs = questions; // <-- saved current state ref to tempQs
    
    ...

    tempQs[temp[0]-1].question = temp1[1]; // <-- mutated state ref
    tempQs[temp1[0]-1].question = temp[1];  // <-- mutated state ref
    this.setState({questions : tempQs},console.log(questions)); // <-- saved state ref
}

解决方案

questions浅拷贝到 new 数组引用中以进行更新。这应该允许react的状态/道具参考测试检测到状态是一个新对象并重新呈现。

const {questions} = this.state;
let tempQs = [...questions]; // <-- spread existing array into new array