无法将切换值从活动更改为不活动

Trouble changing toggle value from active to not active

背景

我在我的 Redux 应用程序中添加了一个切换按钮,允许某人切换他们是否喜欢特定的电视节目。当我单击按钮一次时,我可以将其打开(使按钮处于活动状态),但是当我再次单击它时,该值不会恢复为原始值(按钮未处于活动状态)。

我已经尝试过的

semantic-ui-react 文档给出了 an example of usuage,但我不确定如何将此逻辑合并到我当前的代码中,因为我已经在使用 handleWatchlist 回调来更改状态.

我知道问题出在我处理传递到我按钮的活动 属性 的值的方式上。在这里,我传递的 watchlistValue 始终为 true 或 false。

        <Popup
           trigger={
               <Button
                 toggle
                 active={watchlistValue}
                 onClick={(_) => this.handleWatchlist(programId, 
                   watchlistValue)} 
                 icon='heart'
                      />}
            content="Add to Watchlist."
            size='tiny'/>

这是我当前的 handleWatchlist 方法。

handleWatchlist = (programId, watchlistValue) => {

    this.props.toggleWatchlist(programId, watchlistValue)

  }

这是我如何定义我希望切换其监视列表值(心形按钮)的程序。

let program = this.props.program ? this.props.program : this.props.programs[this.props.match.params.id - 1]

let programId = this.props.program ? this.props.program.id : null

let watchlistValue = this.props.program ? this.props.program.watchlist : null

如果您需要在一个页面上查看所有内容,这里是 link 到 whole file

切换功能已经更新了数据库中我的监视列表项的值。在DOM中,点击它使其激活一次。不幸的是,它不会关闭(到一个错误的值)。

预先感谢您的宝贵时间,如果我需要提供更多详细信息,请告诉我。

您的操作缺少 watchlist 键,导致切换值始终为 true

来自actions/toggleWatchlist.js

    // dispatched action has a `type` and an `id`
    .then(res => dispatch({type: 'TOGGLE_WATCHLIST', id: programId}))

来自 reducers/programReducer.js:

    // action.watchlist is undefined so !action.watchlist is always true
    programToBeToggled.watchlist = !action.watchlist

请注意何时何地切换值,您应该只切换一次,无论是在动作中还是在减速器中,因此请确保您不修复上述问题只是为了在两者中切换动作和减速器,取消切换。

在你的 reducer 中改变

let programToBeToggled = copyOfPrograms.find(program => program.id === action.id);
programToBeToggled.watchlist = !action.watchlist;

let programIndex = copyOfPrograms.findIndex(program => program.id === action.id);
copyOfPrograms[programIndex].watchlist = !copyOfPrograms[programIndex].watchlist;

copyOfPrograms.find 正在创建一个新对象,您正在切换其 watchList 值。但是,这不会更改您随后从减速器返回的 copyOfPrograms 中的布尔值。

带有控制台日志的完整案例,以帮助发现错误:

case 'TOGGLE_WATCHLIST':

    /*
        Make a deep copy of our current state by using JSON.stringify to turn our array of programs into a string.
        After we have created the stringifiedPrograms, we then use JSON.parse to turn it back into a brand new array of objects.
        We then take our copyOfPrograms and find the specific program that we want to update (here we find it by id).
        After isolating that program, we update the value of watchlist.
        Then we return a copy of state, with the program key set to our copyOfPrograms array of objects.
        Updating my programToBeToggled watchlist value still updates it in the copyOfPrograms array.
    */
    console.log('state.programs:');
    console.log(state.programs);

    let stringifiedPrograms = JSON.stringify(state.programs);
    console.log('stringifiedPrograms:');
    console.log(stringifiedPrograms);

    let copyOfPrograms = JSON.parse(stringifiedPrograms);
    console.log('copyOfPrograms:');
    console.log(copyOfPrograms);

    let programIndex = copyOfPrograms.findIndex(program => program.id === action.id);
    copyOfPrograms[programIndex].watchlist = !copyOfPrograms[programIndex].watchlist;
    console.log('copyOfPrograms after switcheroo:');
    console.log(copyOfPrograms);

    return {...state, programs: copyOfPrograms};