子节点更改时,Reactjs不会重新呈现

时间:2018-03-25 11:29:52

标签: reactjs babeljs

我使用Reactjs设计了一个带有两个子节点按钮和行的表格。

更改每个子节点的值后,父节点将接收新状态

但没有重新渲染,为什么?

obj's rc=1
obj's rc=2
obj's rc=1

'table-row'的东西,第3列是数字,修改后,相关的按钮不会改变它的值,反之亦然

<!DOCTYPE html>
<html>
<head>
    <title> w3du </title><meta charset="utf-8">

    <!-- Bootstrap -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
    <style>
        .quarcol {
            width:25%
        }
        .vmidcol {
            vertical-align:middle
        }
        .cyan {
            color:#fff;
            background-color:#63aae7
        }
        .blue {
            color:#fff;
            background-color:#60a0e0
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title text-center">Panel</h3>
            </div>
            <div id="canvas"></div>
        </div>
    </div>

    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.js"></script>
    <script src="https://cdn.bootcss.com/react/15.6.1/react.js"></script>
    <script src="https://cdn.bootcss.com/react/15.6.1/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.js"></script>
    <script src="https://cdn.bootcss.com/js-signals/1.0.0/js-signals.js"></script>

    <script type="text/babel">

“按钮”内容,修改后,关联的表格行不会更改其值

    var BudgetTableRow = React.createClass({
        getInitialState : function(){
            return {
                n     : this.props.n,
                price : this.props.price
            };
        },
        handleChangeNum : function(e){
            this.setState({
                n : e.target.value
            });
            this.props.callback(this.props.idx, e.target.value);
        },
        render : function(){
            var styfull = {
                width : '100%',
                height : '30%',
            };
            var stycenter = {
                verticalAlign : 'middle',
                horizontalAlign : 'middle'
            };
            return (
                <tr className={this.props.color}>
                    <td className="quarcol text-center monofont" style={stycenter}>
                        <a href="#" data-toggle="tooltip" title={"<h1>"+this.props.label+"</h1>"}>{this.props.name}</a>
                    </td>

                    <td className="quarcol"><input name={this.props.label+'-price'}
                        className="form-control text-center monofont"
                        type="text" defaultValue={this.state.price} style={styfull}
                        onChange={this.handleChangePrice}
                    /></td>

                    <td className="quarcol"><input name={this.props.label+'-n'} 
                        className="form-control text-center monofont"
                        type="text" defaultValue={this.state.n} style={styfull}
                        onChange={this.handleChangeNum} onFocus={this.handleFocus} onBlur={this.handleBlur}
                    /></td>

                    <td className="quarcol text-center monofont" style={stycenter}>
                        {this.state.price * this.state.n}
                    </td>
                </tr>
            );
        }
    });

父节点,console.log()做得对,但表单没有重新渲染,我使用了unique-key,这是不是this.state.items.map?

    var BudgetTableButton = React.createClass({
        getInitialState : function(){
            return {
                n : this.props.n
            };
        },
        handelClick : function(e){
            e.preventDefault();
            var n = (this.state.n=="0" || this.state.n=="") ? "1" : "0";
            this.setState({
                n : n
            });
            this.props.callback(this.props.idx, n);
        },
        render : function(){
            var cls = (this.state.n=="0" || this.state.n=="") ? null : 'btn-info';
            return (
                <button className={'btn ' + cls} onClick={this.handelClick}>{this.props.label} {this.state.n}</button>
            );
        }
    });

2 个答案:

答案 0 :(得分:0)

你没有改变状态。

handleCallback : function(idx, n){
            var items = [...this.state.items];
            items[idx].n = n;
            this.setState({
                items : items
            });
        }

答案 1 :(得分:0)

您的示例中的问题是您使用的是两种状态。

(我会在这里谈谈按钮组件,但两种情况都是一样的) 您可能已经知道,本地状态只能触发它所属组件的更新。

您正尝试将按钮的状态与主应用的状态同步。但是 getInitialState 仅在初始渲染时调用,而不是在重新渲染时调用(info here)。

为了做你想做的事,你需要从道具获取按钮/行信息,而不是从状态(你已经在道具中获得它们) )。

此外,我会删除孩子的状态,因为你不需要它。最好将状态保持在顶级组件中,并且只将道具和函数(如回调fn)传递给子级。

因此,在这种情况下,如果您将按钮更改为以下代码,则可以完美地运行:

var BudgetTableButton = React.createClass({
    handelClick : function(e){
        e.preventDefault();
        var n = this.props.n === "0" || this.props.n === "" ? "1" : "0";
        this.props.callback(this.props.idx, n);
    },
    render : function(){
        var cls = (this.props.n=="0" || this.props.n=="") ? null : 'btn-info';
        return (
            <button className={'btn ' + cls} onClick={this.handelClick}>{this.props.label} {this.props.n}</button>
        );
    }
});