【问题标题】:React Component rewrites parent's stateReact Component 重写父级的状态
【发布时间】:2021-11-23 16:59:16
【问题描述】:

我是 React 的新手,所以我需要一些帮助 我有一个具有类似结构的组件

class App extends React.Component{
     constructor(props) {
        super(props);
        this.state = {
            ...
            portfolio: []
            ...
        }
        ...
        this.userDataUpdatesSubscribe = this.userDataUpdatesSubscribe.bind(this);
        this.dealComplete = this.dealComplete.bind(this);
        ...
    }
async componentDidMount() {
        ...
        await this.userDataUpdatesSubscribe();
        ...
    }
userDataUpdatesSubscribe(){
//fs here is a Firebase Firestore SDK
//firebase.initializeApp(firebaseConfig);
//const fs = firebase.firestore();
        fs.collection('users').doc(...).onSnapshot(
            e => {
                this.portfolioInit(e.data().portfolio).then(v =>
                    this.setState({
                        portfolio: v,
                        ...
                    })
                );
            }
        );
    }
async portfolioInit(stocks){
        let a = [];
        for (const v of stocks) {
            let i;
                await this.getPrice(v.ticker).then(e => {
                    i = e.trade.p
                });
            a.push({
                ticker: v.ticker,
                name: StocksData[v.ticker].name,
                price: await i,
                avgPrice: v.avgPrice,
                count: v.count
            });
        }
        return a;
    }
async getPrice(ticker, date=null){
        let a;
        let u = ...;
        await fetch(
            u,
            {
                ...
            }
        ).catch(() => {...}).then(
             async e => {
                a = await e.json();
            }
        )
        return await Promise.resolve(a);
    }
render(){
   <...>
      <TheProblemComponent p={this.state.portfolio} .../>
   </...>
}
} 

所以我有一个组件,用于更新 Firestore 快照的状态。我不在数据库中存储价格,但我需要它,所以我使用 getPrice 方法返回价格。当我得到所有价格时,状态会更新。然后我向其传达具有类似结构的数据

const TheProblemComponent = (p) => {
  const makeDeal() => {
    let x = p.p;
    ...
    some calculations
    ...
    for(let i = 0; i < x.lenght; i++){
      x[i] = {
         ticker: x[i].ticker,
         avgPrice: x[i].avgPrice,
         count: x[i].count
      } // so here i just delete price and name properties which are from props
    }
    fs.collection('users').doc(...).update({portfolio: x, ...}).then(() => {
       ...some actions
    })
  }
  return <Button
           onClick={() => {console.log(p.p); makeDeal()}}
         ></Button>
}

又是这样。我有一个父组件,它在 Firestore 快照上状态更新。数据库中的投资组合有 avgPrice、count 和 ticker。在我的组件中,它还具有我从 getPrice 方法收到的价格和不变的名称。我将此状态组合作为不应修改父状态的道具发送给 ProblemComponent,但确实如此。即使在 makeDeal 函数之前执行,console.log() 也会打印没有价格和名称的数组。我试图在数据库中存储价格和名称,但我不想这样做

【问题讨论】:

    标签: javascript reactjs firebase


    【解决方案1】:

    您似乎正在通过传递的道具改变父状态,因为您正在改变p 道具。

    const makeDeal() => {
      let x = p.p; // <-- saved reference to p.p (portfolio??)
    
      ...
      some calculations
      ...
    
      for(let i = 0; i < x.lenght; i++){
        x[i] = { // <-- mutation!!
          ticker: x[i].ticker,
          avgPrice: x[i].avgPrice,
          count: x[i].count
        }
      }
    
      fs.collection('users')
        .doc(...)
        .update({ portfolio: x, ... })
        .then(() => {
          ...some actions
        });
    }
    

    要解决,浅拷贝您要更新的数据。我建议还使用更具描述性的变量名称,以便代码更具可读性。

    const makeDeal() => {
      const portfolio = [...p.p]; // <-- copy array into new array reference
    
      ...
      some calculations
      ...
    
      for(let i = 0; i < portfolio.length; i++){
        portfolio[i] = { // <-- update the copy
          ticker: portfolio[i].ticker,
          avgPrice: portfolio[i].avgPrice,
          count: portfolio[i].count
        }
      }
    
      fs.collection('users')
        .doc(...)
        .update({ portfolio, ... })
        .then(() => {
          ...some actions
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-20
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 2016-09-14
      相关资源
      最近更新 更多