简体   繁体   English

如何根据Redux操作结果更新React组件

[英]How can I update a React component depending on redux action outcome

I have a React component that contains an input. 我有一个包含输入的React组件。 The component dispatches a redux action that calls an API. 该组件调度一个调用API的redux操作。 I want to display a "SUCCESS" message per component but I can't work out how to get the message, other than through the reducer? 我想显示每个组件的“ SUCCESS”消息,但是除了通过reducer之外,我不知道如何获取该消息? But if I was to do it through the reducer it would just be a general message that would update all the form components? 但是,如果我要通过reducer进行操作,那将是一条将更新所有表单组件的通用消息吗?

//COMPONENT //零件

export default class Stock extends React.Component {


constructor(props) {
    super(props);

    this.state = {
        value: "",
        id: this.props.hit['Name of Item'],
    }
  }

handleChange(e){
    e.preventDefault();
    this.setState({value: e.target.value});
}

handleClick(e){
    e.preventDefault();
    this.props.dispatch(updatePosStock(this.state.value, this.state.id));
}

render() {

    return (
            <div className="item">
                <p>{this.props.hit['Name of Item']}: {this.props.hit.Quantity}</p>
                <p>Stock ID: {this.props.hit.objectID}</p>
                <div className="control">
                <input className="input" value={this.state.value} type="text" onChange={this.handleChange.bind(this)} />
                <a href="" onClick={this.handleClick.bind(this)} >save</a>

                //MESSAGE TO DISPLAY HERE DEPENDING ON handleClick

                </div>
            </div>
        )
    }
}

//ACTION //行动

export function updatePosStock(product, stock){
return function(dispatch) {
    axios.post('/api/v1/product/', {
        product,
        stock
    })
    .then((response) => {
        //console.log(response.data);
        return response.data;
        //dispatch({type: 'FETCH_PRODUCT_FULFILLED', payload: response.data})
    })
    .catch((error) => {
        console.log(error);
    })
}
}

If I understand, this component is rendered multiple times on the page and when you trigger action on one, message gets distributed to all the components (because it is not distinguishable between components. 据我了解,此组件在页面上呈现了多次,并且当您在一个组件上触发操作时,消息就会分发到所有组件(因为无法区分这些组件。

So, I'd set message to be something like: 因此,我将消息设置为:

[{
  message: 'Success',
  item: itemId
},
...]

and when sending a data to api I'd send for which item it is being sent and would just push this message to message array, then in place where you want to display message you put 当将数据发送到api时,我将发送要发送的项目,并将此消息推送到消息数组,然后放在要显示消息的位置

{this.displayMessage(messagesVar, index) || ''}

So when display message is not falsy it displays message. 因此,当显示消息不是错误时,它将显示消息。

messageVar is what your reducer updates. messageVar是您的reducer更新的内容。

Display message function is smt like 显示消息功能像

(messages, id) => { 
     currentComponentMsgs = messages.filter((item) => item.id === id);
     return currentComponentMsgs.length > 0 
            ? currentComponentMsgs.mat((item) => item.message).reduce((a,b) => a + ', ' + b}
            : '');
  }

I did not have time to check if it all works, but if you propagate id of each elemnt properly, using this pattern you can even have multiple messages recorder in messagesVar, so it serves as kind of a mailbox for components. 我没有时间检查这一切是否正常,但是如果您正确传播每个元素的ID,则使用此模式,您甚至可以在messagesVar中具有多个消息记录器,因此它可以用作组件的邮箱。 You can use it on all of your components. 您可以在所有组件上使用它。

There are two ways you can achieve this 有两种方法可以实现此目的

1. save your response message (eg 'success') in the form of an array 1.以数组形式保存您的响应消息(例如“成功”)

In this case you can define a state such as feedback: [], for example. 在这种情况下,您可以定义状态,例如: feedback: [], Then you will set the message this way 然后您将以这种方式设置消息

...
//dispatch({type: 'FETCH_PRODUCT_FULFILLED', payload: [ product : response.data]})
..

Then in your component you do the following 然后在您的组件中执行以下操作

...
<input className="input" value={this.state.value} type="text" onChange={this.handleChange.bind(this)} />
<a href="" onClick={this.handleClick.bind(this)} >save</a>

//MESSAGE TO DISPLAY HERE DEPENDING ON handleClick
<p className="feedback">{this.props.feedback[this.state.value] || ''}</p>

Depending on how you import your states in to your components. 取决于将状态导入到组件的方式。

2. Create another property in your redux state or inside this.state={} for example inputKey . 2.在您的redux状态或在this.state={}内部创建另一个属性,例如inputKey Then set inputKey value through handleClick(e, inputKeyValue) You could pass inputKey as a third parameter to the function dispatched and continue with display as should above in you component. 然后通过handleClick(e, inputKeyValue)设置inputKey值。您可以将inputKey作为第三个参数传递给分派的函数,并按照上面在组件中的显示继续进行显示。

I strongly recommend that you handle all your states with redux and avoid using this.state and this.setState() as much as you can. 我强烈建议您使用redux处理所有状态,并尽量避免使用this.statethis.setState()

I hope it helps. 希望对您有所帮助。

Use callback for your action: 使用回调进行操作:

handleClick(e){
    e.preventDefault();
    this.props.dispatch(updatePosStock(this.state.value, this.state.id, 
    (code, message)=>{if (code==='OK')this.setState({displayMessage:true, message:"Successfully saved"})}));
}

///ACTION
export function updatePosStock(product, stock, callback){
return function(dispatch) {
    axios.post('/api/v1/product/', {
        product,
        stock
    })
    .then((response) => {
        callback('OK')
        return response.data;
        //dispatch({type: 'FETCH_PRODUCT_FULFILLED', payload: response.data})
    }) .catch((error) => { callback(error.code, error.message)
        console.log(error);
    })
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM