firebase +反应,setState似乎不会触发重新渲染

时间:2018-08-14 22:13:31

标签: javascript reactjs firebase firebase-realtime-database

我正在使用Firebase作为后端,并且正在为Restaurant实体创建详细视图。一家餐厅有一系列的菜品ID,因此我想在查看餐厅时列出这些菜品。

在菜品列表组件中,我得到了菜品ID数组作为道具。然后,我浏览每个菜肴ID,并从Firebase获取菜肴数据。我在 componentWillReceiveProps 中执行此操作,以获取父组件中的最新状态更新。

这是菜品清单组件:

array(6) {
  [0] =>
  array(4) {
    'item' =>
    string(4) "pear"
    'quality' =>
    int(1)
    'store' =>
    string(4) "bobs"
    'price' =>
    int(3)
  }
  [1] =>
  array(4) {
    'item' =>
    string(6) "banana"
    'quality' =>
    int(2)
    'store' =>
    string(5) "freds"
    'price' =>
    int(1)
  }
  [2] =>
  array(4) {
    'item' =>
    string(7) "coconut"
    'quality' =>
    int(2)
    'store' =>
    string(4) "sams"
    'price' =>
    int(6)
  }
  [3] =>
  array(4) {
    'item' =>
    string(4) "kiwi"
    'quality' =>
    int(2)
    'store' =>
    string(4) "sams"
    'price' =>
    int(4)
  }
  [4] =>
  array(4) {
    'item' =>
    string(5) "apple"
    'quality' =>
    int(3)
    'store' =>
    string(5) "freds"
    'price' =>
    int(2)
  }
  [5] =>
  array(4) {
    'item' =>
    string(4) "lime"
    'quality' =>
    int(3)
    'store' =>
    string(4) "sams"
    'price' =>
    int(5)
  }
}

这是父组件:

class DishList extends Component {
    constructor(props){
        super(props)
        this.state = {
            Dishes: []
        }
    }

    componentWillReceiveProps(props) {
        const tempDishes = []
        props.dishes.map(dish => {
            firebaseDishes.child(dish).on("value", snap => {
                if (tempDishes.findIndex(x => x.id === snap.key) == -1) {
                    // push only if id doesn't exist
                    tempDishes.push({
                        id: snap.key,
                        name: snap.val().name,
                        price: snap.val().price
                    })
                    this.setState({
                        Dishes: tempDishes
                    })
                } else {
                    const updatedTempDishes = tempDishes.slice()
                    updatedTempDishes[updatedTempDishes.findIndex(x => x.id === snap.key)] = {
                        id: snap.key,
                        name: snap.val().name,
                        price: snap.val().price
                    }
                    this.setState({
                        Dishes: updatedTempDishes
                    })
                }
            })
        })
    }

    render(){
        return(
            <div className="dishes">
            {
                this.state.Dishes.map(dish => {
                    return(
                        <DishListItem key={dish.id} 
                                    DishId={dish.id}
                                    DishName={dish.name} 
                                    DishPrice={dish.price}/>
                    )
                })
            }
            </div>
        )
    }
}

有效方法:

  • 页面加载(1)时,菜单会正确填充

什么不起作用:

  • 如果我在Firebase上更新盘子,它不会更新UI上的清单(2)

我检查过的内容

  • 该回调函数可正确进行更新,即,如果我在firebase中更改了菜品条目,则会在snap.val()下获得该数据
  • 状态改变。如果在setState调用之前和之后在setState完成回调中检查状态,我会看到两个状态之间的差异
  • 如果我先清空状态,然后在完成回调中使用新数据再次设置状态,它将更新用户界面

赞:

class Place extends Component {
    constructor(props){
        super(props)
        this.state = {
            Place: {
                name: '',
                address: '',
                dishes: []
            }
        }
    }

    componentDidMount(){
        firebasePlaces.child(this.props.placeId).on("value", snap => {
            this.setState({
                Place: snap.val()
            })
        })
    }

    render(){
        return(
            <div>
                <h1 className="name"> {this.state.Place.name} </h1>
                <h3 className="address"> {this.state.Place.address} </h3>
                <DishList dishes={this.state.Place.dishes} />
            </div>
        )
    }
}

任何暗示为什么会发生这种情况都非常感谢!

0 个答案:

没有答案