Перехват React useState, влияющий на переменную по умолчанию, используемую в состоянии, независимо от операторов распространения, Object.assign и т. Д

#javascript #reactjs #ecmascript-6 #react-hooks #use-state

#javascript #reactjs #ecmascript-6 #реагирующие перехваты #use-state

Вопрос:

Я опытный разработчик js / React, но столкнулся со случаем, который я не могу решить, и я понятия не имею, как это исправить.

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

 const defaultParams = {
  ordering: 'price_asc',
  page: 1,
  perPage: 15,
  attrs: {},
}

const InnerPageContext = createContext()

export const InnerPageContextProvider = ({ children }) => {
  const [params, setParams] = useState({ ...defaultParams })

  const clearParams = () => {
    setParams({...defaultParams})
  }

  console.log(defaultParams)

  return (
    <InnerPageContext.Provider
      value={{
        params: params,
        setParam: setParam,
        clearParams:clearParams
      }}
    >
      {children}
    </InnerPageContext.Provider>
  )
}
 

У меня есть одна кнопка на странице, которая вызывает clearParams функцию, и она должна сбросить параметры до значения по умолчанию.
Но это не работает

Даже когда я console.log(defaultParams) при каждом повторном рендеринге провайдера, кажется, что defaultParams переменная также меняется при изменении состояния

Я не думаю, что это нормально, потому что я использовал {...defaultParams} , и он должен создать новую переменную, а затем передать ее в useState hook.

Я уже пробовал:

 const [params, setParams] = useState(Object.assign({}, defaultParams))
const clearParams = () => {
  setParams(Object.assign({}, defaultParams))
}
 
 const [params, setParams] = useState(defaultParams)
const clearParams = () => {
  setParams(defaultParams)
}
 
 const [params, setParams] = useState(defaultParams)
const clearParams = () => {
  setParams({
    ordering: 'price_asc',
    page: 1,
    perPage: 15,
    attrs: {},
  })
}
 

Ни один из вышеперечисленных методов не работает, кроме 3-го, где я жестко запрограммировал тот же объект, defaultParams что и .
Идея состоит в том, чтобы сохранить где-нибудь параметры dafult и, когда пользователь очистит параметры, восстановить их.
У вас, ребята, есть какая-нибудь идея, как это сделать?

Редактировать: Вот как я обновляю свои параметры:

 const setParam = (key, value, type = null) => {
    setParams(old => {
      if (type) {
        old[type][key] = value
      } else old[key] = value
      console.log('Params', old)
      return { ...old }
    })
  }
 

Комментарии:

1. Я думаю, нам нужно немного больше контекста того, как вы это используете. Учитывая этот (по общему признанию, довольно грубый) пример, кажется, что все работает так, как ожидалось. Поэтому я бы предположил, что проблема заключается в коде, не показанном здесь.

Ответ №1:

пожалуйста, покажите, как вы обновляете «параметры».

если в коде есть что-то подобное «params.attrs.test = true», тогда параметры по умолчанию будут изменены

если old[type] это не простой тип, он сохраняет ссылку на тот же объект в defaultParams. defaultParams.attrs === params.attrs . Поскольку во время инициализации вы разрушаете объект, но не его вложенные объекты.

проблема здесь: old[type][key] = value

решение:

 const setParam = (key, value, type = null) => {
    setParams(old => {
      if (type) {
        old[type] = {
          ...old[type],
          key: value,
        }
      } else old[key] = value
      return { ...old }
    })
  }
 

Комментарии:

1. ты спас меня, друг, Это случилось со мной в компоненте