Reactjs 如何在不更新存储的情况下将成功状态传递回组件
我在react redux中有一个简单的表单,用于尝试向数据库添加用户,如果成功,则显示一条成功消息。然而,我不确定这样做的最佳方法。我有以下资料:Reactjs 如何在不更新存储的情况下将成功状态传递回组件,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我在react redux中有一个简单的表单,用于尝试向数据库添加用户,如果成功,则显示一条成功消息。然而,我不确定这样做的最佳方法。我有以下资料: onSubmit = e => { ... const newUser = { user object here } this.props.registerUser(newUser); } 在组件将接收道具(下一步): 在渲染()中: 用于显示一个成功组件,提供更多信息。如果成功,还有一个条件检查来隐藏表单 在我的操作中: .t
onSubmit = e => {
...
const newUser = { user object here }
this.props.registerUser(newUser);
}
在组件将接收道具(下一步)
:
在渲染()中
:
用于显示一个成功组件,提供更多信息。如果成功,还有一个条件检查来隐藏表单
在我的操作中
:
.then(res => {
dispatch({
type: REGISTRATION_SUCCESS,
payload: true
});
})
在减速器中
:
const initialState = false;
export default function(state = initialState, action) {
switch (action.type) {
case REGISTRATION_SUCCESS:
return action.payload;
default:
return state;
}
}
在组合传感器中:
export default combineReducers({
success: successReducer
});
在这种情况下,我基本上使用服务器的响应向组件发送一个成功道具,更新状态,这将强制react渲染并再次遍历条件语句,隐藏表单并显示新的成功块
然而,当我进入redux开发工具时,我看到商店中的状态现在是
true
,如果用户离开,状态仍然是这样。有没有更好的方法来实现这一目标?我发现这可能应该与组件状态本身隔离,但不确定如何做到这一点,因为操作和服务器响应都是通过redux实现的 Redux是一个状态机,而不是一个消息总线,因此请尝试使您的状态值表示应用程序的当前状态,而不是发送一次性消息。这些可以通过操作创建者的返回值进行修改。成功或失败可能仅仅是因为存在/缺少来自动作创建者的错误
如果您确实想要存储用户信息,您可以通过拥有注册用户来派生“was successful”状态,并清除组件装载上的任何现有注册用户
// actions.js
export const clearRegisteredUser = () => ({
type: SET_REGISTERED_USER,
payload: null,
})
export const register = (userData) => async (dispatch) => {
// async functions implicitly return a promise, but
// you could return it at the end if you use the .then syntax
const registeredUser = await api.registerUser(userData)
dispatch({
type: SET_REGISTERED_USER,
payload: registeredUser,
})
}
// reducer.js
const initialState = { registeredUser: null }
const reducer = (state = initialState, { type, payload }) => {
switch(type) {
case SET_REGISTERED_USER: {
return {
...state,
registeredUser: payload,
}
}
default: {
return state
}
}
}
// TestComponent.js
class ExampleComponent extends Component {
state = {
registrationError: null,
}
componentWillMount() {
this.props.clearRegistered()
}
handleSubmit = async (formData) => {
try {
this.props.register(formData)
} catch(error) {
// doesn't really change application state, only
// temporary form state, so local state is fine
this.setState({ registrationError: error.message })
}
}
render() {
const { registrationError } = this.state
const { registeredUser } = this.props
if (registrationError) {
return <FancyError>{registrationError}</FancyError>
} else if (registeredUser) {
return <SuccessComponent name={this.props.registeredUser.name} />
} else {
return <UserForm onSubmit={this.handleSubmit} />
}
}
}
//actions.js
导出常量clearRegisteredUser=()=>({
类型:设置\注册\用户,
有效载荷:空,
})
导出常量寄存器=(用户数据)=>async(分派)=>{
//异步函数隐式返回一个承诺,但
//如果使用.then语法,则可以在末尾返回它
const registeredUser=await api.registerUser(userData)
派遣({
类型:设置\注册\用户,
有效载荷:registeredUser,
})
}
//reducer.js
常量initialState={registeredUser:null}
const reducer=(state=initialState,{type,payload})=>{
开关(类型){
案例集\注册\用户:{
返回{
……国家,
registeredUser:有效载荷,
}
}
默认值:{
返回状态
}
}
}
//TestComponent.js
类ExampleComponent扩展组件{
状态={
注册错误:null,
}
组件willmount(){
this.props.clearRegistered()
}
handleSubmit=async(formData)=>{
试一试{
此.props.register(formData)
}捕获(错误){
//不会真正改变应用程序状态,只是
//临时表单状态,所以本地状态是可以的
this.setState({registrationError:error.message})
}
}
render(){
const{registrationError}=this.state
const{registeredUser}=this.props
如果(注册错误){
返回{registrationError}
}else if(registeredUser){
返回
}否则{
返回
}
}
}
如果注册后确实不需要用户信息,可以直接执行api调用,而不使用Redux
class ExampleComponent extends Component {
state = {
registered: false,
registrationError: null,
}
handleSubmit = async (formData) => {
try {
await api.registerUser(formData)
this.setState({ registered: true })
} catch(error) {
this.setState({ registrationError: error.message })
}
}
render() {
const { registered, registrationError } = this.state
if (registrationError) {
return <FancyError>{registrationError}</FancyError>
} else if (registered) {
return <SuccessComponent name={this.props.registeredUser.name} />
} else {
return <UserForm onSubmit={this.handleSubmit} />
}
}
}
类示例组件扩展组件{
状态={
注册:假,
注册错误:null,
}
handleSubmit=async(formData)=>{
试一试{
等待api.registerUser(formData)
this.setState({registered:true})
}捕获(错误){
this.setState({registrationError:error.message})
}
}
render(){
const{registered,registrationError}=this.state
如果(注册错误){
返回{registrationError}
}否则,如果(已注册){
返回
}否则{
返回
}
}
}
最后,尽可能避免在组件状态中保留redux状态的副本。它很容易导致同步问题。这里有一篇关于避免派生状态的好文章:首先,我认为您不应该使用Redux存储来保存本质上是本地状态的内容 如果是我,我可能会尝试直接从组件进行api调用,如果成功,然后写入redux存储。这样可以避免在组件中使用派生状态
也就是说,如果您想这样做,我建议componentWillUnmount。这将允许您进行另一个Redux调用,当您离开页面时,该调用会将您的注册布尔值恢复为false 在发送注册成功之前,我建议您发送一个请求操作,可能是注册请求。请求操作应将成功字段设置为false。稍后我将尝试返回答案-但请查看我的这个问题-以及其中的链接:-我将其称为挂起/加载/成功/失败模式。API调用是否成功,不是本地状态。
export default combineReducers({
success: successReducer
});
// actions.js
export const clearRegisteredUser = () => ({
type: SET_REGISTERED_USER,
payload: null,
})
export const register = (userData) => async (dispatch) => {
// async functions implicitly return a promise, but
// you could return it at the end if you use the .then syntax
const registeredUser = await api.registerUser(userData)
dispatch({
type: SET_REGISTERED_USER,
payload: registeredUser,
})
}
// reducer.js
const initialState = { registeredUser: null }
const reducer = (state = initialState, { type, payload }) => {
switch(type) {
case SET_REGISTERED_USER: {
return {
...state,
registeredUser: payload,
}
}
default: {
return state
}
}
}
// TestComponent.js
class ExampleComponent extends Component {
state = {
registrationError: null,
}
componentWillMount() {
this.props.clearRegistered()
}
handleSubmit = async (formData) => {
try {
this.props.register(formData)
} catch(error) {
// doesn't really change application state, only
// temporary form state, so local state is fine
this.setState({ registrationError: error.message })
}
}
render() {
const { registrationError } = this.state
const { registeredUser } = this.props
if (registrationError) {
return <FancyError>{registrationError}</FancyError>
} else if (registeredUser) {
return <SuccessComponent name={this.props.registeredUser.name} />
} else {
return <UserForm onSubmit={this.handleSubmit} />
}
}
}
class ExampleComponent extends Component {
state = {
registered: false,
registrationError: null,
}
handleSubmit = async (formData) => {
try {
await api.registerUser(formData)
this.setState({ registered: true })
} catch(error) {
this.setState({ registrationError: error.message })
}
}
render() {
const { registered, registrationError } = this.state
if (registrationError) {
return <FancyError>{registrationError}</FancyError>
} else if (registered) {
return <SuccessComponent name={this.props.registeredUser.name} />
} else {
return <UserForm onSubmit={this.handleSubmit} />
}
}
}