Reactjs NextJS:处理Connect/OwnProps/GetInitialProps的最佳方法

Reactjs NextJS:处理Connect/OwnProps/GetInitialProps的最佳方法,reactjs,redux,next.js,Reactjs,Redux,Next.js,我想用123呈现应用程序。 但是,如果MapStateTops中的状态有一个foo键,且其值为abc,则组件将呈现abc 我可以检查一下自己的道具 @connect((state, ownProps) => ({...state, ...ownProps}), () => {}) class App extends Component 合并自己的道具和状态。但如果我开始在Redux中发送操作来更新foo,状态将始终是abc。ownProps将始终覆盖状态中的键 我可以在组件挂载时发

我想用123呈现应用程序。
但是,如果MapStateTops中的状态有一个
foo
键,且其值为
abc
,则组件将呈现
abc

我可以检查一下自己的道具

@connect((state, ownProps) => ({...state, ...ownProps}), () => {})
class App extends Component
合并自己的道具和状态。但如果我开始在Redux中发送操作来更新foo,状态将始终是
abc
。ownProps将始终覆盖状态中的键

我可以在组件挂载时发出一个动作

componentDidMount() {
  dispatchFoo(this.props.value)
}
当组件装载时,我将分派值

@connect((state)=>state,()=>{})`

商店将更新为
abc
,即自己道具的价值。 Redux将更新,组件将再次渲染。
但这一次,状态将是abcin

@connect((state)=>state,()=>{})

什么是最好的方式来设置这样的事情?最好不需要组件渲染两次(我使用的是SSR)


在我的例子中,我使用NextJS并进行API调用以获取getInitialProps中的数据。返回getInitialProps会将数据放在props上。这些道具都是给App的。当用户更改状态时,应用程序需要的是来自状态的数据,而不是道具。您有两个选项:

1。使用默认道具

可以将defaultProps定义为组件类本身的属性,以设置该类的默认props。这用于未定义的道具,但不用于空道具。例如:

请参阅React的博客

2。设置初始状态

在减速器内,您可以设置状态初始值,这些值将通过
mapStateToProps
提供:

const initialState = {
    foo: false
};

export default function(state = initialState, action) {
    console.log('action', action);
    switch (action.type) {
        case types.SOME_ACTION:
            return {
                ...state,
            foo: true
            };
        case types.ANOTHER_ACTION:
            return {
                ...state,
                foo: false
            };
        default:
            return state;
    }
}

一般来说,我看不到在
mapStateToProps
中覆盖相同的道具有任何意义,因为它会阻止你的应用程序被redux更新。

如果我没有错,你想实现一些称为非受控组件的东西。如果是这样的话,我建议你按照以下方式实施


Class Page extends React.Component{
  static getInitialProps(){
    return {foo:"Some Value"}
  }
  render(){
    return <Provider store={createStore(reducer,{foo:this.props.foo})}>
      <App/>
    </Provider>

  }
}

类页扩展了React.Component{
静态getInitialProps(){
返回{foo:“某个值”}
}
render(){
返回
}
}
然后你的app.js将

@connect(mapStateToProps,{dispatchFoo})
Class App extends React.Component{
 componentDidMount(){
   this.props.dispatchFoo({foo:"some new value"});
 }
 render(){
   <div>{this.props.foo}</div>
 }

}
@connect(mapStateToProps,{dispatchFoo})
类应用程序扩展了React.Component{
componentDidMount(){
this.props.dispatchFoo({foo:somenewvalue});
}
render(){
{this.props.foo}
}
}

为什么要在两个不同的位置/以两种不同的方式将同一道具钥匙传递给部件?(也称为连接和内联)。这听起来像是一种非常容易出错的代码编写方法。我不是。我正在用值
123
传递应用程序道具
foo
。之后,用户操作通过redux更改
foo
的值。Connect将商店状态映射到道具。州政府有
foo
键。是的,正是我所描述的。为什么您在redux中的州会有一个与内联道具相同的密钥?您应该有单独的道具键,用于从连接的存储中内联发送的内容。我正在使用NextJS并进行API调用,以在
getInitialProps
中获取数据。返回
getInitialProps
会将数据放在props上。这些道具将提供给
App
。当用户更改状态时,应用程序需要的是来自当前状态的数据,而不是道具。您能否详细说明如何使用此
单独道具
?不要将
foo
作为道具传递到组件上,让connect传递该道具。如果最初需要不同的值,则使用该初始值设置存储

Class Page extends React.Component{
  static getInitialProps(){
    return {foo:"Some Value"}
  }
  render(){
    return <Provider store={createStore(reducer,{foo:this.props.foo})}>
      <App/>
    </Provider>

  }
}
@connect(mapStateToProps,{dispatchFoo})
Class App extends React.Component{
 componentDidMount(){
   this.props.dispatchFoo({foo:"some new value"});
 }
 render(){
   <div>{this.props.foo}</div>
 }

}