用动态键反应setState

时间:2018-01-03 19:41:33

标签: javascript reactjs ecmascript-6

我在使用updateSelection在React中为状态对象创建动态密钥时遇到了一个简单的问题,但在尝试了几个小时后我无法弄清楚如何修复它。

有关详细信息,请参阅代码中的注释,以及下面的简短概述。

场景:用户点击给定页面中的选项,并调用下面的computed property names方法。此方法使用新信息更新状态。

问题:使用state = { userSelection: {} } const updateSelection = page => { const { pageName, category, multiple } = page; const selection = { pageName, category } // If `multiple` is false, pages must be unique in the state object. // This currently works fine. if (!multiple) { this.setState(prevState => ({ userSelection: { ...prevState.userSelection, [pageName]: selection } })); // New state for userSelection is now this: // { // Page 1: {pageName: "Page 1", category: X}, // Page 2: {pageName: "Page 2", category: Y} // } return; } // If `multiple` is true for a page, the same page key can be added to // the state object as long as the category is different. If the category // is the same, the page is replaced just like when `multiple` is false. // The desired result for userSelection would look something like this: // { // Page 1: {pageName: "Page 1", category: X}, // Page 2: {pageName: "Page 2", category: Y}, // Page 2: {pageName: "Page 2", category: Z}, // Page 2: {pageName: "Page 2", category: W, other unique props} // } } 我认为(?)使得键在对象内部是唯一的,并且将替换任何将来的同名键。在某些情况下,我想允许多个选择同一页面,这是我无法弄清楚的部分。如果效果更好,我愿意把我的状态变成一个对象数组。

pageName

更新:对于删除网页,输入可以是deletePage,可以作为参数传递给与updateSelection类似的Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click Using db As SMSTEntities = New SMSTEntities() Try Dim Query = From PhoneNumber In db.PhoneNumberOfCustomers Where PhoneNumber.PhoneNumber.Equals(txtNumber.Text) Select PhoneNumber If Query.Any() Then MessageBox.Show("Your Searched Data " + txtNumber.Text + " Is Present in Database, Please Insert the Releated Information") Else MessageBox.Show("Your Searched Data " + txtNumber.Text + " Is Not Present in Database") End If Catch ex As Exception MessageBox.Show(ex.Message) End Try End Using End Sub 方法。

1 个答案:

答案 0 :(得分:1)

如果您希望将数组用于每个页面的多个值,请执行以下操作:

{ 
  "Page 1": [ {pageName: "Page 1", category: X} ], 
  "Page 2": [
    {pageName: "Page 2", category: Y},
    {pageName: "Page 2", category: Z},
    {pageName: "Page 2", category: W, other unique props}
  ]
}

然后您可以调整以下代码来添加/替换数组中的项目:



function updateSelection ({pageName, category, multiple}) {
  const selection = {pageName, category} // assuming more props here
  if (!multiple) {} // TODO keep old code or change to arrays too
  
  this.setState(prevState => {
    const {userSelection} = prevState
    if (!userSelection.hasOwnProperty(pageName)) {
      userSelection[pageName] = []
    }
    let categoryWasReplaced = false
    const nextUserSelection = {
      ...userSelection,
      [pageName]: userSelection[pageName].map(item => {
        // TODO use .filter() if needed to remove from selection
        if (item.category === category) {
          categoryWasReplaced = true
          return selection
        }
        return item
      })
    }
    if (!categoryWasReplaced) {
      nextUserSelection[pageName].push(selection)
    }
    return {userSelection: nextUserSelection}
  })
}

// ### test ###
let state = {userSelection: {}}
const mockSetState = f => {
  state = {...state, ...f(state)}
}
const testUpdateSelection = updateSelection.bind({state, setState: mockSetState})
testUpdateSelection({pageName: 'Page 1', category: 'X', multiple: true})
testUpdateSelection({pageName: 'Page 2', category: 'Y', multiple: true})
testUpdateSelection({pageName: 'Page 2', category: 'Y', multiple: true})
testUpdateSelection({pageName: 'Page 2', category: 'Y', multiple: true})
testUpdateSelection({pageName: 'Page 2', category: 'Z', multiple: true})
testUpdateSelection({pageName: 'Page 2', category: 'W', multiple: true})
console.log(state)