首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在reducer中更改状态后,组件不会重新呈现

在reducer中更改状态后,组件不会重新呈现
EN

Stack Overflow用户
提问于 2019-05-27 00:47:04
回答 3查看 221关注 0票数 0

假设我有一个链接,当单击它时,会将一个随机数添加到我的状态对象queue中的数组中。整个state.queue数组都会显示在我的页面上,并在我们单击链接时更新。我目前有一个链接,它应该做一些类似的事情,但是在我的reducer改变了状态(向数组中添加了一个新项)之后,我的页面不会(重新?)呈现我的组件,所以页面不会更新。

我应该怎么做才能在我的页面上显示整个state.queue,包括当我点击链接时动态更新?这就是我所拥有的:

Channel.js

代码语言:javascript
复制
class Channel extends Component {
    constructor(props) {
        super(props);
        this.state = {
            queue: [],
            // more initializations
        };
      ...
    }
    ...
    render() {  
        return (
            <div>
            {/*This part is never called because this.state.queue never has anything in it! */}
             {this.state.queue && 
                this.state.queue.length > 0 &&
                    <div>
                        <ul>
                            {this.state.queue.map((queuedItem, i) =>
                                <li key={i}>{queuedItem}</li>
                            )}
                        </ul>
                    </div>}


                <div>

                    <QResults
                        allQueryResults={this.state.queryState}
                        requestHandler={queueNewRequest}
                    />
                </div>
            </div>
        );
    }
}

function mapStateToProps(state) {
    const{queue} = state
    return {queue}
}

 function mapDispatchToProps(dispatch) {
    return ({
        queueNewRequest: (newRequestData) => { dispatch({type: newRequestData}) }
    })
} 

export default withRouter(connect(mapStateToProps , mapDispatchToProps )(Channel))

QResults.js

代码语言:javascript
复制
export default class QResults extends Component {
    render() {
        const {requestHandler} = this.props

        return (
            <ul>
                {this.props.allQueryResults.items.map((trackAlbum, i) =>
                    <li key={i}>
                        <a href='#' 
                        onClick={
                            () => requestHandler(trackAlbum.name)}>
                            Some link
                        </a>
                    </li>
                )}
            </ul>
        )
    }
}

actions.js

代码语言:javascript
复制
export const QUEUE_NEW_REQUEST = 'QUEUE_NEW_REQUEST'

export function queueNewRequest(newRequestInfo) {
    return dispatch => {
        dispatch({
            type: QUEUE_NEW_REQUEST,
            payload: newRequestInfo
        })
    }
}

reducers.js

代码语言:javascript
复制
import { combineReducers } from 'redux'

function reducer1(state = {}, action) {
    ...
}

function reducer2(state = {}, action) {
    switch (action.type) {
        case QUEUE_NEW_REQUEST:
             return {
                ...state,
                /*queue: [...state.queue,action.payload],*/ //compiler complains that 'TypeError: state.queue is not iterable'
                queue:[action.payload]
            } 
        default:
            return state
    }
}
const rootReducer = combineReducers({
    reducer1,
    reducer2
})

export default rootReducer
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-27 00:52:14

this.state.queue指的是Channel组件的本地状态。它不是redux状态。您将this.state.queue初始化为一个空数组,然后再也不会更改它(例如,您永远不会调用this.setState)。

如果你想在redux中与状态交互,这就是mapStateToProps的用武之地。因为你有一个看起来像这样的mapStateToProps:

代码语言:javascript
复制
function mapStateToProps(state) {
    const{queue} = state
    return {queue}
}

通道组件将获得一个名为的队列属性,您可以通过this.props.queue.与其交互

因此,修复方法是更新Channel以与道具交互。您最有可能想要删除this.state.queue,因为它似乎没有任何用途,并且由于其名称而引起混淆。

代码语言:javascript
复制
{this.props.queue && 
  this.props.queue.length > 0 &&
    <div>
      <ul>
        {this.state.queue.map((queuedItem, i) =>
          <li key={i}>{queuedItem}</li>
        )}
      </ul>
    </div>
  }

此外,您设置root reducer的方式使您的redux状态看起来如下所示:

代码语言:javascript
复制
{
  reducer1: {}, // not sure what this contains, since reducer 1 was omitted
  reducer2: {
    queue: [],
  }
}

因此,如果这确实是你想要的redux状态的样子,你的到props的映射状态将需要更新为:

代码语言:javascript
复制
function mapStateToProps(state) {
    const {queue} = state.reducer2;
    return {queue};
}
票数 1
EN

Stack Overflow用户

发布于 2019-05-27 01:05:24

一旦您使用connectstate对象连接到props,您将在props中获得返回的对象。看看这个:https://react-redux.js.org/using-react-redux/connect-mapstate#return

因此,您只需在Channel.js文件中将this.state.queue更改为this.props.queue

并且您的组件不会呈现,因为它不依赖于更改后的props。因此,执行上述建议的更改应该可以解决问题。

票数 2
EN

Stack Overflow用户

发布于 2019-05-27 01:38:45

除了所有关于将this.state.queue更改为this.props.queue的响应之外,我还需要做一些事情。在我的reducer2中初始化队列

代码语言:javascript
复制
function reducer2(state = {queue:[]}, action) {
    switch (action.type) {
        case QUEUE_NEW_REQUEST:
            return {
                ...state,
                queue: [...state.queue,action.payload],
            }
        default:
            return state
    }
}

Channel.js中更改mapStateToProps

代码语言:javascript
复制
function mapStateToProps(state) {
    const{queue} = state.reducer2
    return {queue}
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56315519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档