ReactJs,在全局状态更改时丢失子组件的局部状态

时间:2020-02-03 11:15:29

标签: javascript reactjs

我不了解某些ReactJs的行为,需要帮助。

我有一个根功能组件(“索引”),其中包含另一个功能组件(“预览”)。 该预览组件包含其他几个功能组件(“ InlineField”)。

该应用程序是一种简单的表单,其中InlineField是呈现输入的组件,并且还包含一个状态,用于了解该字段是“打开”还是“关闭”(关闭时显示为文本,打开时显示为文本)。显示为输入)。

全局状态是使用“索引”级别的钩子定义的,并通过props下移到字段(我使用Context进行了相同的尝试)。此状态包含所有表单值。

InlineField组件使用挂钩仅维护其本地状态(处于打开状态/处于关闭状态)。 更改输入后,它会更新状态(索引级别),从而触发索引及其子级的重新呈现。 转换为当前编辑的字段(本地状态为open的InlineField组件)以刷新并丢失其状态值。

我的问题: 如何确保这些InlineField组件即使在更新全局状态后仍保持其状态? 我也可以将InlineField组件状态也移到全局状态,但是我认为这没有多大意义。

我肯定出了点问题...

谢谢!


编辑:添加了代码示例

索引组件:

import React, { useState, useEffect } from "react"

import Layout from "../components/layout"


const IndexPage = () => {


  const [formValues, setFormValues] = useState({
    name: 'Myname',
    email: 'myemail@mail.com',
  })

  const onFormValueChange = (key, value) => {
    setFormValues({...formValues, [key]: value})
  }

  return (
    <Layout>
      <Preview
        key="previewyaknow"
        formValues={formValues}
        onFieldChange={setFormValues}
      />
    </Layout>
  )
}
export default IndexPage

预览组件:

import React from 'react'
import { Box, TextField } from "@material-ui/core"
import { InlineField } from './inlineField'

export const Preview = ({formValues, onFieldChange}) => {

  return (
    <>
      <Box display="flex" alignItems="center">
        <InlineField 
          value={formValues.email}
          onChange={onFormValueChange}
          id="email"
          field={<TextField value={formValues.email}/>>>}
        />
    </>
  )
}

InlineEdit组件

import React, { useState, useEffect } from "react"

export const InlineField = ({onChange, value, id, field}) => {
  const [isEdit, setIsEdit] = useState(false)

  const onBlur = (e) => {
    setIsEdit(false)
  }

  let view = (<div>{value}</div>);
  if (isEdit) { 
    view = (
      <FieldContainer className={classes.fieldContainer}>
        {React.cloneElement(field, { 
          'onBlur': onBlur, 
          'autoFocus': true, 
          'onChange': (e) => {
            onChange(id, e.target.value) 
          }
        })
        }
      </FieldContainer>
    )
  }

  return (
    <div onClick={()=>setIsEdit(!isEdit)}>
      {view}
    </div>
  )
}

0 个答案:

没有答案