Reactjs 如何在不丢失状态/重新创建组件的情况下呈现实例列表?

Reactjs 如何在不丢失状态/重新创建组件的情况下呈现实例列表?,reactjs,react-native,Reactjs,React Native,尝试用一些动画制作我自己的React路由器。撞到砖墙 我正在渲染一堆屏幕。 堆栈可以弹出或推送 我的问题是,当堆栈更改时,状态将丢失,并且再次调用构造函数来破坏以前的状态(使堆栈无用)。 我该怎么做 创建屏幕(之后,我们推到状态为的堆栈) 渲染屏幕 render() { return ( <View {...this.props} onLayout={(event) => this.onLayout(event)}

尝试用一些动画制作我自己的React路由器。撞到砖墙

我正在渲染一堆屏幕。
堆栈可以弹出或推送

我的问题是,当堆栈更改时,状态将丢失,并且再次调用构造函数来破坏以前的状态(使堆栈无用)。 我该怎么做

创建屏幕(之后,我们推到状态为的堆栈)

渲染屏幕

render() {
    return ( <View 
            {...this.props} 
            onLayout={(event) => this.onLayout(event)} 
            pointerEvents={this.state.isAnimating ? 'none' : undefined} 
            >
        { this.renderStackOfScreens() }
    </View>);
};

renderStackOfScreens() {
    // Render screens.
    return this.state.stackOfScreens
    .map((eachScreen, index) => {

        // Render second last screen IF animating. Basically because we have a screen animating over the top.
        if (index === this.state.stackOfScreens.length - 2 && this.state.isAnimating) {
            return (
                <Animated.View 
                    key={eachScreen.props.screenId + '_parent'} 
                    style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>
                    { eachScreen }
                </Animated.View>
            );
        }

        // Render last screen which is animated.
        if (index === this.state.stackOfScreens.length - 1) {
            return (
                <Animated.View 
                    key={eachScreen.props.screenId + '_parent'}
                    style={this.getOffset(this.state.animatedScreenOffset)}>
                    { eachScreen }
                </Animated.View>
            );
        }
    })
    // Remove the undefined values.
    .filter((eachScreen) => !!eachScreen);
}
render(){
返回(this.onLayout(事件)}
pointerEvents={this.state.isAnimating?'none':未定义}
>
{this.renderStackOfScreens()}
);
};
renderStackOfScreens(){
//渲染屏幕。
返回此.state.stackOfScreens
.map((每个屏幕,索引)=>{
//如果设置动画,则渲染最后一个屏幕。基本上是因为我们有一个在顶部设置动画的屏幕。
if(index==this.state.stackOfScreens.length-2&&this.state.isAnimating){
返回(


屏幕类型作为唯一的子项传入。

一旦卸载组件,其状态将永远消失。您可能会认为“我有一个对组件的变量引用,所以即使它已卸载,它仍然保持其状态,对吗?”不,React不是那样工作的。卸载组件等于销毁它。即使重新安装“相同”组件,就React而言,它是一个全新的组件,具有全新的构造函数调用、装载生命周期等。因此,您需要放弃将React组件本身作为历史堆栈保存在阵列中的方法

令人沮丧,我知道。相信我,我也遇到过同样的问题

解决方案是从组件本身中取出视图/屏幕状态并将其提升到父级。本质上,您将状态保留在父级中的一个数组中,然后将它们作为道具传递到视图/屏幕本身。这可能看起来像是一种违反直觉的“非反应性”操作方式,但是。状态通常应该“提升”到所有组件都需要从其访问的最接近的公共祖先的级别。在这种情况下,您需要在视图/屏幕本身之上的级别访问您的状态,因此您需要提升它

这里有一些伪代码来说明

现在,您的应用程序似乎是这样构造的:

// App state
state: {
  // stackOfScreens is React components.
  // This won't work if you're trying to persist state!
  stackOfScreens: [
    <Screen />,
    <Screen />,
    <Screen />
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >{ea}</View>
      }
    }
  </div>
}
// App state
state: {
  // stackOfScreens is an array of JS objects.
  // They hold your state in a place that is persistent,
  // so you can modify it and render the resulting
  // React components arbitrarily
  stackOfScreens: [
    {
      name: "screen#1",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#2",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#3",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >
          <Screen stateData={ea} callback={this.screenCallback} />
        </View>
      }
    }
  </div>
}
//应用程序状态
声明:{
//堆垛式筛网是反应组件。
//如果你试图保持这种状态,这是行不通的!
堆垛筛:[
,
,
]
}
//应用程序渲染功能
render(){
返回
{
this.state.stackOfScreens.map((ea,i)=>{
返回{ea}
}
}
}
相反,它应该是这样的:

// App state
state: {
  // stackOfScreens is React components.
  // This won't work if you're trying to persist state!
  stackOfScreens: [
    <Screen />,
    <Screen />,
    <Screen />
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >{ea}</View>
      }
    }
  </div>
}
// App state
state: {
  // stackOfScreens is an array of JS objects.
  // They hold your state in a place that is persistent,
  // so you can modify it and render the resulting
  // React components arbitrarily
  stackOfScreens: [
    {
      name: "screen#1",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#2",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#3",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >
          <Screen stateData={ea} callback={this.screenCallback} />
        </View>
      }
    }
  </div>
}
//应用程序状态
声明:{
//stackOfScreens是一个JS对象数组。
//他们把你的状态保持在一个持久的地方,
//因此,您可以修改它并渲染结果
//任意反应组分
堆垛筛:[
{
名称:“屏幕#1”,
foo:“某种‘屏幕’状态”,
酒吧:“更多的州,
巴兹:“等等。”
},
{
名称:“屏幕#2”,
foo:“某种‘屏幕’状态”,
酒吧:“更多的州,
巴兹:“等等。”
},
{
名称:“屏幕#3”,
foo:“某种‘屏幕’状态”,
酒吧:“更多的州,
巴兹:“等等。”
},
]
}
//应用程序渲染功能
render(){
返回
{
this.state.stackOfScreens.map((ea,i)=>{
返回
}
}
}

请注意,在正在渲染的屏幕组件上添加了一个
回调
道具。这样,您就可以从屏幕内部触发对渲染屏幕“状态”(实际上在父级中跟踪)的更改。

一旦卸载组件,其状态将永远消失。您可能会认为“我有一个对组件的变量引用,所以即使它被卸载,它仍然保持它的状态,对吗?“不,React不是这样工作的。卸载组件等于销毁它。即使你重新装载“相同的”“组件,就React而言,它是一个全新的组件,具有全新的构造函数调用、装载生命周期等。因此,您需要放弃将React组件本身作为历史堆栈保存在阵列中的方法

令人沮丧,我知道。相信我,我也遇到过同样的问题

解决方案是从组件本身中取出视图/屏幕状态并将其提升到父级。本质上,您将状态保留在父级中的一个数组中,然后将它们作为道具传递到视图/屏幕本身。这可能看起来像是一种违反直觉的“非反应性”操作方式,但是。状态通常应该“提升”到所有组件都需要从其访问的最接近的公共祖先的级别。在这种情况下,您需要在视图/屏幕本身之上的级别访问您的状态,因此您需要提升它

这里有一些伪代码来说明

现在,您的应用程序似乎是这样构造的:

// App state
state: {
  // stackOfScreens is React components.
  // This won't work if you're trying to persist state!
  stackOfScreens: [
    <Screen />,
    <Screen />,
    <Screen />
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >{ea}</View>
      }
    }
  </div>
}
// App state
state: {
  // stackOfScreens is an array of JS objects.
  // They hold your state in a place that is persistent,
  // so you can modify it and render the resulting
  // React components arbitrarily
  stackOfScreens: [
    {
      name: "screen#1",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#2",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#3",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >
          <Screen stateData={ea} callback={this.screenCallback} />
        </View>
      }
    }
  </div>
}
//应用程序状态
声明:{
//堆垛式筛网是反应组件。
//如果你试图保持这种状态,这是行不通的!
堆垛筛:[
,
,
]
}
//应用程序渲染功能
render(){
返回
{
this.state.stackOfScreens.map((ea,i)=>{
返回{ea}
}
}
}
相反,它应该是这样的:

// App state
state: {
  // stackOfScreens is React components.
  // This won't work if you're trying to persist state!
  stackOfScreens: [
    <Screen />,
    <Screen />,
    <Screen />
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >{ea}</View>
      }
    }
  </div>
}
// App state
state: {
  // stackOfScreens is an array of JS objects.
  // They hold your state in a place that is persistent,
  // so you can modify it and render the resulting
  // React components arbitrarily
  stackOfScreens: [
    {
      name: "screen#1",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#2",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
    {
      name: "screen#3",
      foo: "Some sort of 'screen' state",
      bar: "More state,
      baz: "etc."
    },
  ]
}

// App render function
render() {
  return <div>
    {
      this.state.stackOfScreens.map((ea, i) => {
        return <View key={i} >
          <Screen stateData={ea} callback={this.screenCallback} />
        </View>
      }
    }
  </div>
}
//应用程序状态
声明:{
//stackOfScreens是一个JS对象数组。
//他们把你的状态保持在一个持久的地方,
//因此,您可以修改它并渲染结果
//任意反应组分
堆垛筛:[
{
名称:“屏幕#1”,
foo:“某种‘屏幕’状态”,
酒吧:“更多的州,
巴兹:“等等。”
},
{
名称:“屏幕#2”,
foo:“某种‘屏幕’状态”,
酒吧:“更多