如何在React渲染中显示而不重新渲染,自动更改Mobx存储实例的值?

时间:2019-10-30 09:13:08

标签: javascript reactjs mobx mobx-react

如何获取mobx类的实时属性?

我创建了一个mobx商店实例,在其中计算年月日 几个行星。 每个星球都是使用PlanetStore函数的实例 与setInreval,总会增加几天和几年。 我列出了所有实例。

现在,我想在react-mobx组件网络中实时显示几年和几天的变化。但是,它不可观察。我该怎么办??

@observer
class Calendar extends Component{

    render(){
        let planets = planetStore.Planets *just getting names of planets not relevant
        let planetArr=[]
        for(let i=1; i<planets.length; i++){
            let key= Object.keys(planets[i])
            planetArr.push(key)
        }
        this.planets=planetArr
        planets.forEach(e=> calanderStore.loadPlanets(e))
        console.log(planetArr)
       console.log(calanderStore.list)
       calanderStore.showPercent()       
        return (
        <div id='calendar'> {this.planets.map((planet, index) => <Cal planet={planet} key={index}/> )} </div> )       
    }

}

export default Calendar

*为每个星球创建一个实例

class CalendarItem{
  @observable currentPrecent=0
  @observable planetName

  constructor(planetName,currentPrecent) {
        this.planetName=planetName
        this.currentPrecent=currentPrecent
        this.dayCounter=0
        this.yearCounter=-1
      }

      @action makeInstnace=(planet)=>{
        this.planetName=planet
        let currentPrecent=this.currentPrecent
        let dayCounter=this.dayCounter
        let yearCounter=this.yearCounter
       let planetData=new 
  CalendarItem(`${planet}`,`${currentPrecent}`,`${yearCounter}`,`${dayCounter}`)

   return (
      planetData
   )
      }


    }   
export default new CalendarItem();
@observer
class Cal extends Component{

    constructor(props) {
        super(props)
        this.state={rerender:''}
        this.planetName=this.props.planet
        this.currentPrecent=0   
        this.dayCounter=0
        this.yearCounter=-1
    }

    render(){
        let planet=this.props.planet

      **here i take the planet from the list of instances i made in CalandareStore Below**
 dayCounter=JSON.parse(JSON.stringify(calanderStore.list[planetIndex].dayCounter))
      console.log(dayCounter)
      let yearCounter=planet.yearCounter



        return(
            <div className="calendaritem">       **the instance is being updated
            <span>{dayCounter}</span>              but it is not observed in here
            <div></div>
            <div>{calanderStore.list[planetIndex].yearCounter}</div>

class CalanderStore {
@observable list=[] *list of instances*

@action loadPlanets=(planetName)=>{
            console.log(planetName)
            planetName=JSON.parse(JSON.stringify(planetName))
            planetName=Object.keys(planetName)
            console.log(planetName)
            let ifexist=this.findPlanetFromList(planetName)    
            if(ifexist.length==0){        
          let newPlanet=CalendarItem.makeInstnace(planetName)

           return this.list.push(newPlanet)
            }
              }

 @action  showPercent= (id)=> {
          console.log("Calander test now")   
          this.list.forEach(id=>{
                id=JSON.parse(JSON.stringify(id)) 
                let index=planetStore.findPlanetIndex(id.planetName)
          let  test=planetStore.Planets[index][id.planetName].animationDuration['animation-duration']

               test=test.replace('s','0')
               test=parseInt(test)
               console.log(test)
            let setTimer=(id)=>{
              // id=id[0]
              // planetName=id[0].planeName

              // id=JSON.parse(JSON.stringify(id))

              if (id.currentPrecent < 100) {
                console.log(id)
                id.currentPrecent += 1;  
                id.dayCounter=Math.round(id.currentPrecent*planetStore.Planets[index][id.planetName].daysInyear/100)      
              }
              else {
                id.currentPrecent=0
                id.dayCounter=0;
                id.yearCounter+=1;
                console.log(id.dayCounter)
              }
            }
            // let getanimationduration=this.getAnimeDuration
            // let totalDuration = getanimationduration(planetName)
              setInterval(() => {
              setTimer(id)}, test);

          })
        }

2 个答案:

答案 0 :(得分:0)

是的,您可以控制组件是否应该更新,是否具有react组件类的功能

shouldComponentUpdate ( nextProps, nextState, nextContext ) {
    /* compare nextState with your current states properties if you want to update on any basis return true if you want to render the component again  */
    return true; // will re-render component , 
    return false; // do not re-render component even if you change component states properites
}

答案 1 :(得分:0)

我不太确定您的代码在做什么,但是我注意到您在setInterval内使用@action

Mobx操作仅适用于当前堆栈,setTimeoutPromisesetInterval中的代码不在同一堆栈中运行。 Mobx具有用于编写异步代码的特殊功能。

Writing asynchronous actions