首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React.memo()重置状态

React.memo()重置状态
EN

Stack Overflow用户
提问于 2019-07-11 10:56:03
回答 1查看 1.1K关注 0票数 1

我有一些从对象数组中呈现的输入。

当我输入一个输入时,我映射到数组上,找到相应的对象并设置输入值。

问题:在一个输入中键入一些字符,更改输入,键入字符。重复此操作,观察先前的输入被清除,有时在某些输入中出现一些随机字符。

是什么导致了这种行为?

如果我将React.memo()从SearchBar中删除,问题就不再出现。

要使它与React.memo()一起工作,我需要做些什么。

代码语言:javascript
复制
const shouldSkipComponentUpdate = (prevProps, props) =>
prevProps.value === props.value;

const SearchBar = React.memo((props) => {
  const { label, width, hasSearch, handleSearchChange, value } = props;
    return (
      <div width={width} style = { { margin: "15px", display: "inline" } }>
        {label}
        {hasSearch && (
          <SearchInput
            onChange={handleSearchChange}
            value={value}
            label={label}
          />
        )}
      </div>
    );
  }, (prevProps, props) => shouldSkipComponentUpdate(prevProps, props));


function DevicesContainer() {
  const [searchBoxes, setSearchBoxes] = React.useState(() => {
    return [
      {
        id: 1,
        label: '',
        width: '5%',
        hasSearch: false,
        value: ''
      },
      {
        id: 2,
        label: 'ID',
        width: '5%',
        value: '',
        hasSearch: false
      },
      {
        id: 3,
        width: '10%',
        label: 'Name',
        value: '',
        hasSearch: true
      },
      {
        id: 4,
        width: '10%',
        label: 'Owner',
        value: '',
        hasSearch: true
      },
      {
        id: 5,
        width: '7%',
        label: 'Availability',
        value: '',
        hasSearch: false
      },
      {
        id: 6,
        width: '10%',
        label: 'Location',
        value: '',
        hasSearch: true
      },
      {
        id: 7,
        width: '20%',
        label: 'Environment',
        value: '',
        hasSearch: true
      },
      {
        id: 8,
        width: '10%',
        label: 'Firmware',
        value: '',
        hasSearch: true
      },
    ];
  });
  function handleSearchChange(event, label) {
    const {
      target: { value }
    } = event;
    const updated = searchBoxes.map(elem => {
      if (elem.label === label) {
        return { ...elem, value };
      }
      return elem;
    });
    setSearchBoxes(updated);
  }
  return (
    <main>
      <SearchBars
        searchBars={searchBoxes}
        handleSearchChange={handleSearchChange}
        />
    </main>
  );
}

function SearchBars(props) {
  const { searchBars, handleSearchChange } = props;
  return (
    <div style={ { margin: '20px' } }>
      {searchBars.map(elem => (
        <SearchBar
          key={elem.id}
          label={elem.label}
          width={elem.width}
          hasSearch={elem.hasSearch}
          value={elem.value}
          handleSearchChange={handleSearchChange}
          />
      ))}
    </div>
  );
}

function SearchInput(props) {
  const { onChange, value, label } = props;
  return (
    <input
      type="search"
      value={value}
      placeholder="Search"
      onChange={event => onChange(event, label)}
      />
  );
}

  ReactDOM.render(
    <DevicesContainer />,
    document.getElementById('root')
  );

代码链接https://codepen.io/Apoptotic/pen/ZdPpQG

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-11 20:43:28

您可以更改handleSearchChange()函数。参见关于文档行为的setState。您可能还会注意到,此函数异步运行。我刚刚将映射函数移到setSearchBox更新句柄中,以便将数据应用到以前的状态。

代码语言:javascript
复制
  function handleSearchChange(event, label) {
    const {
      target: { value }
    } = event;


    setSearchBoxes((prevSearchBoxes) => {
      let s = [...prevSearchBoxes];
      let updated = s.map(elem => {
        if (elem.label === label) {
          return { ...elem, value };
        }
        return elem;
      });
      return updated;
    });
  }

另外,请参见React中的以下说明。

与类组件中的setState方法不同,useState不会自动合并update对象。您可以通过将函数更新器表单与对象扩展语法相结合来复制此行为:

代码语言:javascript
复制
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

另一个选项是useReducer,它更适合于管理包含多个子值的状态对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56987642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档