React Server Rendering:警告:setState(...):只能更新安装组件

时间:2017-07-10 06:49:41

标签: reactjs firebase react-router

我学习反应+火力棒。我还读到了关于React服务器渲染和放大器的信息。我想测试&看看服务器呈现我的应用程序是什么样子。所以我使用ReactDOMServer来渲染我的组件,并且可以渲染我非常简单的组件,但是当我尝试使用rebase包在我的应用程序和Firebase之间同步数据的组件时,我遇到了问题。这是我得到的警告:

  

警告:setState(...):只能更新安装组件。这个   通常意味着你在componentWillMount()之外调用了setState()   服务器。这是一个无操作。请检查应用程序的代码   成分

这是我的代码:

应用组件

import React from 'react';
import Header from './Header';
import Orders from './Orders';
import Inventory from './Inventory';
import SampleFishes from '../sample-fishes';
import Fish from './Fish';
import base from '../base';

class App extends React.Component{
    constructor(){
        super();
        this.addFish = this.addFish.bind(this);
        this.loadSampleFishes = this.loadSampleFishes.bind(this);
        this.addToOrder = this.addToOrder.bind(this);
        this.liveUpdateFish = this.liveUpdateFish.bind(this);
        this.removeFish = this.removeFish.bind(this);
        this.removeOrder = this.removeOrder.bind(this);
        this.state={
            fishes:{},
            orders:{}
        };
    }
    componentWillMount(){
        let prevOrder = localStorage.getItem(`${this.props.params.store}-order`);
        this.ref = base.syncState(`${this.props.params.store}/fishes`,{
            context:this,
            state:`fishes`,
             then(){
                if(prevOrder){
                this.setState({orders: JSON.parse(prevOrder)});
                }
            }
        });
    }
    componentWillUnmount(){
        base.removeBinding(this.ref);
    }
    componentWillUpdate(nextProps,nextState){
        localStorage.setItem(`${this.props.params.store}-order`,JSON.stringify(nextState.orders));
    }
    loadSampleFishes(){
        let fishes = {...this.state.fishes,...SampleFishes};
        this.setState({fishes});
    }
    addFish(fish){
        let fishes = {...this.state.fishes};
        fishes[`fish-${Date.now()}`]= fish;
        this.setState({fishes});
    }
    addToOrder(key){
        let orders = {...this.state.orders};
        orders[key] = orders[key]+1 ||1;
        this.setState({orders});
    }
    liveUpdateFish(fish,k){
        let fishes = {...this.state.fishes};
        fishes[k] = fish;
        this.setState({fishes});
    }
    removeFish(key){
        let fishes = {...this.state.fishes};
        fishes[key] = null;
        this.setState({fishes});
        this.removeOrder(key);
    }
    removeOrder(key){
        let orders = {...this.state.orders};
        delete orders[key];
        this.setState({orders});
    }
    render(){
        return (
            <div className="catch-of-the-day">
                <div className="menu">
                    <Header tagline="Fresh SeaFood Market"/>
                    <ul>
                        {
                            Object.keys(this.state.fishes).map(key=><Fish addToOrder={this.addToOrder} id={key} key={key} fish={this.state.fishes[key]} />)
                        }
                    </ul>
                </div>
                <Orders orders={this.state.orders} fishes={this.state.fishes} removeOrder={this.removeOrder}/>
                <Inventory addFish={this.addFish} loadSampleFishes={this.loadSampleFishes} fishes={this.state.fishes} liveUpdate={this.liveUpdateFish} removeFish={this.removeFish} />
            </div>
        );
    }
}
export default App;

订单组件

import React from 'react';
import Order from './Order';
import {formatPrice} from '../helpers';
class Orders extends React.Component{
    render(){
        const orderIDs = Object.keys(this.props.orders);
        let list = null;
        if(orderIDs.length===0){
            list = <li>OOPS there is no item</li>;
        }else{
           list = Object.keys(this.props.orders).map(key=><Order removeOrder={this.props.removeOrder} fish={this.props.fishes[key]} key={key} index={key} order={this.props.orders[key]}/>)
        }
        const total = orderIDs.reduce((prev,index)=>{
            if(!this.props.fishes[index]) return prev;
            if(!this.props.fishes[index].price) return prev;
            return prev+this.props.fishes[index].price*this.props.orders[index]},0);

        return (

            <div className="order-wrap">
                <h2>Your Orders</h2>
                <ul className="order">
                    {list}
                 <li className="total">total is {formatPrice(total)}</li>
                 </ul>
            </div>

        );
    }
}
export default Orders;

订购组件

import React from 'react';
import {formatPrice} from '../helpers';
class Order extends React.Component{
    render(){
        const removeButton = <button onClick={e=>this.props.removeOrder(this.props.index)}>❌</button>
        return (
            <li><span>{this.props.order}x {this.props.fish.name}</span><span className="price">{formatPrice(this.props.fish.price)}</span>{removeButton}</li>

        );
    }
}
export default Order;

广告资源

import React from 'react';
import AddFishForm from './AddFishForm'

class Inventory extends React.Component{
    constructor(props){
        super(props);
        this.returnInventory = this.returnInventory.bind(this);
        this.handleChanges = this.handleChanges.bind(this);
    }
    handleChanges(e,key){
        const fish = this.props.fishes[key];
        const updatedFish = {...fish,
        [e.target.name] : e.target.value
    };
    this.props.liveUpdate(updatedFish,key);

    }
    returnInventory(key){
            const fish = this.props.fishes[key];
            return(
                <div className="fish-edit" key={key}>
                 <input name="name" value={fish['name']}   type="text" placeholder="fish name" onChange={e=>this.handleChanges(e,key)} />                      
                   <input name="price" value={fish['price']}  type="text" placeholder="fish price" onChange={e=>this.handleChanges(e,key)} />                
                   <select name="status" value={fish['status']} onChange={e=>this.handleChanges(e,key)}>
                        <option value="available">Fresh!</option>
                        <option value="unavailable">Sold Out!</option>
                   </select>                    
                   <textarea name="desc" value={fish['desc']} type="text" placeholder="fish desc" onChange={e=>this.handleChanges(e,key)}></textarea>                     
                   <input name="image" value={fish['image']}    type="text" placeholder="fish image" onChange={e=>this.handleChanges(e,key)} />
                   <button onClick={e=>this.props.removeFish(key)}>- Remove Fish</button> 
                   </div>
            )
    }
    render(){
        return (
            <div>
                <h2>Inventory</h2>
                {
                    Object.keys(this.props.fishes).map(key=>this.returnInventory(key))
                }
                <AddFishForm addFish={this.props.addFish}/>
                <button onClick={this.props.loadSampleFishes}>Load Sample Fishes</button>
            </div>

        );
    }
}
export default Inventory;

鱼类组件

import React from 'react';
import {formatPrice} from '../helpers';

class Fish extends React.Component{
    addOrder(k){
        console.log(k);
        this.props.addToOrder(k);
    }
    render(){
        let available = this.props.fish.status ==='available';
        let buttonText = available?'Order it':'Sold Out';
        return (<li className="menu-fish" id={this.props.id}>
            <img src={this.props.fish.image} alt={this.props.fish.name}/>
            <h3 className="fish-name">{this.props.fish.name}<span className="price">{formatPrice(this.props.fish.price)}</span>
            </h3>
            <p className="fish-desc">{this.props.fish.desc}</p>
            <button disabled={!available} onClick={(e)=>this.addOrder(this.props.id)}>{buttonText}</button>
        </li>);
    }
}
export default Fish;

0 个答案:

没有答案