在父组件的状态更改时重新渲染子组件

时间:2019-03-13 18:29:27

标签: reactjs react-native react-navigation

我正在使用react-navigation在两个屏幕之间导航,同时在两个屏幕之间传递数据。

流量: 屏幕A(传递数据)->屏幕B->(更新并传回数据)屏幕A。

在屏幕A中,我正在使用一个子组件,在从屏幕B接收回数据时需要对其进行更新/重新渲染。

我已经检查了数据是否正确传递,并且我肯定主屏幕中子组件正在使用的状态正在更新。我只是无法弄清楚为什么在读取状态的新值后子组件没有重新渲染?

主屏幕:

updateCount(data) {
    // Logic to update state of a counter variable
    this.setState({ count: data })
}

// and then later on in the code, I'm calling the child Component 'B'        
<B prop={this.state.count} />

组件B:

componentWillMount() {
// based on value of this.props.count, I'm setting the value of 'text' in this component
    if(this.props.count == 1) {
       this.setState({text: 'abc'})
    } else {
       this.setState({text: 'cde'})
    }
}

// later on in the code, render method:
<View>
   <Text>
     {this.state.text}
   </Text>
</View>

3 个答案:

答案 0 :(得分:0)

更新组件B:(下面的代码)

    constructor(props) {
            super(props);
            this.state = {
                count: props.count
            };
         }

        componentWillReceiveProps(nextProps) {
           if (nextProps.count != this.props.count){
                this.setState({
                count: nextProps.count
            })
          }
        }

       componentDidMount() {
             this.setTextValue();
       }

         componentWillUpdate() {
             this.setTextValue();
       }

         setTextValue = () => {
           if(this.state.count == 1) {
               this.setState({text: 'abc'})
           } else {
              this.setState({text: 'cde'})
            }
         }

包括其余代码。

研究lifecycle methods的反应很好。

答案 1 :(得分:0)

回答我的问题,因为我意识到我没有更新组件代码中的prop值以反映父元素状态的变化。

我想这就是为什么我首先如此困惑的原因,因为状态改变的重新渲染是React工作的核心。我使用react-devtools调试并确定了子组件的生命周期。现在一切正常!不知道我是否需要钩子/其他生命周期方法来实现此简单功能,但我感谢大家的帮助!

答案 2 :(得分:-1)

您将不得不与此一起使用componentDidUpdate。但是,如果使用钩子,则会同时敲除componentDidMount和componentDidUpdate。对于基于类的示例,可能与此类似。

<?php 
    include("includes/dbh.inc.php");
    $sql = "SELECT u.`id` AS user_id, u.`company_name` AS company FROM users u;";
    // $sql = "SELECT * FROM users;";
    $result = mysqli_query($conn,$sql);
    $result_array = mysqli_fetch_array($result,MYSQLI_NUM);
?>

<section class="main-container">
    <div class="main-wrapper">
        <h1>Invoice Form</h1>
            <form class="invoice-form" >
                <div style="overflow-x:auto;">
                    <table class="table-header" id="tableData">
                        <tr >
                            <th>Select Client</th>
                            <th>INVOICE NUMBER</th>
                            <th>Today's Date</th>
                            <th>Due Date</th>
                            <th>Item Description</th>
                            <th>Unit Price (R/Unit)</th>
                            <th>Amount of Units</th>
                            <th>Subtotal (R)</th>
                        </tr>
                        <tr>
                            <td>
                                <select name="selected_value[]">
                                    <?php while ($resultCheck = mysqli_fetch_array($result)):;?>
                                    <option value="<?php echo $resultCheck['user_id']; ?>"><?php echo $resultCheck['company']; ?></option>
                                  <?php endwhile;?>
                                </select>
                            </td>
                            <td>
                                <input type="text" name="invoice_number[]" placeholder="19-001" required>
                            </td>
                            <td>
                                <input type="date" name="date_issued[]" placeholder="2018/02/28" required>
                            </td>
                            <td>
                                <input type="date" name="date_due[]" placeholder="2018/02/28" required>
                            </td>
                            <td>
                                <input type="text" name="item[]" placeholder="Web Hosting" required>
                            </td>
                            <td>
                                <input onkeyup="MultiplyInputs()" type="val" name="price_per_unit[]" id="price_per_unit" placeholder="0" min=0 required>
                            </td>
                            <td>
                                <input onkeyup="MultiplyInputs()" type="val" name="unit[]" id="unit" placeholder="0" min="0" required>
                            </td>
                            <td>                        
                                <span name="price[]" id="price"></span>
                            </td>
                        </tr>
                    </table>
                    <table class="table-total" >
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td>Total (R)</td>
                        <td><span name="total_price" id="total_price"></span></td>
                    </table>
                <BUTTON type="submit" name="submit" id="submit">Create Invoice</BUTTON><button type="button" name="add" id="add" class="btn btn-success" >Add More</button>
            </div>  
        </form>
        </div>
    </section>

    <script>
        $(document).ready(function(){
            var i = 0;
            $('#add').click(function(){
                i++;
                $('#tableData').append('<tr id="row'+i+'"><td><select name="selected_value[]"><?php while ($resultCheck = mysqli_fetch_assoc($result)):; ?><option value="<?php echo $resultCheck["user_id"]; ?>"><?php echo $resultCheck["fullname"]; ?></option><?php endwhile;?></select></td><td><input type="text" name="invoice_number[]" placeholder="19-001" required></td><td><input type="date" name="date_issued[]" placeholder="2018/02/28" required></td><td><input type="date" name="date_due[]" placeholder="2018/02/28" required></td><td><input type="text" name="item[]" placeholder="Web Hosting" required></td><td><input onkeyup="MultiplyInputs()" type="val" name="price_per_unit[]" id="price_per_unit" placeholder="0" min=0 required></td><td><input onkeyup="MultiplyInputs()" type="val" name="unit[]" id="unit" placeholder="0" min="0" required></td><td><span name="price[]" id="price"></span></td><td><button name="remove" id="'+i+'" class="btn btn-danger btn_remove">X</button></td></tr>');
            });

            $(document).on('click','.btn_remove', function(){
                var button_id = $(this).attr("id");
                $("#row"+button_id+"").remove();
            });

            $('#submit').click(function(){
                $.ajax({
                    async: true,
                    url: "includes/invoice.inc.php",
                    method: "POST",
                    data: $('.invoice-form').serialize(),
                    success:function(rt){
                        alert(rt);
                        $('.invoice-form')[0].reset();
                    }
                });
            });
        });
    </script>

但是,根据文档,这些方法被认为是旧方法,您应该在新代码中避免使用它们:

UNSAFE_componentWillMount()

将其丢弃以支持componentDidMount和componentDidUpdate,或切换到钩子(这是最佳选择!)