onClick array.pu sh перезаписывает предыдущие элементы - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь добавить несколько значений к моему key: [] клику, но он продолжает перезаписывать мою предыдущую запись

  const handleClick = e => {
    console.log('click ', e)
    let choice = {
      key: e.keyPath[1],
      value: [],
    }
    choice.value.push(e.keyPath[0])

    console.log('choice', choice)
    let newFilterChoice = {
      ...filterChoice,
      [choice.key]: choice.value,
    }

    updateFilter(newFilterChoice)
    console.log('filter', filterChoice)
  }

вывод первого клика выглядит так {role: ['value 1']}, второй клик {role: ['new value']}

ожидаемый результат должен быть {role: ['value 1', 'new value']}

Ответы [ 3 ]

2 голосов
/ 04 мая 2020

В вашем примере вы создаете новую локальную переменную choice каждый раз, когда вызывается эта функция, поэтому choice.values всегда будет начинаться как [].

То, что вы, вероятно, хотите сделать, это переместить эту переменную choice в состояние и обновлять ее каждый раз, когда вы обрабатываете щелчок. Как то так:

const App = () => {
  const [choiceValues, setChoiceValues] = React.useState([]);
  
  const handleClick = React.useCallback((e) => {
    const { value } = e.target.dataset;
    
    setChoiceValues(prevChoiceValues => {
      // Append the new value to the old ones creating a new array (no `prevChoiceValues.push`,
      // otherwise the reference won't change and React won't be able to track your change:
      const nextChoiceValues = [...prevChoiceValues, value];
      
      // Do something else with `nextChoiceValues` here:
      // updateFilter(nextChoiceValues);
      
      // Return them to update the state:
      return nextChoiceValues;
    });
  }, []);
  
  const nextValue = choiceValues.length;
  
  return (
    
    
    { choiceValues.join(', ') }
); } ReactDOM.render ( , document.querySelector ('# app'));
body,
button {
  font-family: monospace;
}

body, p {
  margin: 0;
}

#app {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
}

button {
  margin: 32px 0;
  padding: 8px;
  border: 2px solid black;
  background: transparent;
  cursor: pointer;
  border-radius: 2px;
}
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>
1 голос
/ 04 мая 2020

Вы заменяете ключ новым значением, а не добавляете его.

let newFilterChoice = {
  ...filterChoice,
  [choice.key]: choice.value, // <-- this replaces what used to be there
}

Я думаю, что вы намеревались сохранить ранее установленные значения для ключа, поэтому вам, вероятно, следует сделать следующее:

const oldChoice = filterChoice[e.keyPath[1]];
let choice = {
  key: e.keyPath[1],
  value: oldChoice ? oldChoice.value : []  // <-- keep existing values
}
choice.value.push(e.keyPath[0])
let newFilterChoice = {
  ...filterChoice,
  [choice.key]: choice.value, 
}

Или вы можете избежать создания нового объекта, если в этом нет необходимости, например:

const oldChoice = filterChoice[e.keyPath[1]];
let choice = oldChoice ? oldChoice : {
  key: e.keyPath[1],
  value: [] 
}
choice.value.push(e.keyPath[0])
let newFilterChoice = {
  ...filterChoice,
  [choice.key]: choice.value, 
}
1 голос
/ 04 мая 2020

Если предположить несколько вещей, когда обработчик клика handleClick сработает, choice, newFilterChoice и т. Д. c., Все будут переопределены. Вам может понадобиться что-то вроде this.state или useState ловушка для хранения ваших сессий.

Кроме того, когда вы пытаетесь создать newFilterChoice, choice фактически воссоздается и добавляется.

Вы можете изменить логи c здесь:

let choice = {
  key: e.keyPath[1],
  value: [],
}

Выше value должно относиться к сохраненным вариантам где-то. Вот лучший пример:

const domContainer = document.querySelector('#root');

class App extends React.Component {
  state = {
    choices: []
  };
  handleClick = () => {
    const choices = [...this.state.choices];
    choices.push(new Date());
    this.setState({ choices });
  };
  render() {
    return (
      
        {JSON.stringify(this.state.choices, null, 2)}
Нажмите ); }} ReactDOM.render ( , domContainer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...