输入正在失去对钩更新的关注



我是ReactJ的新手,我正在尝试从输入中读取数据。问题是当我键入一个符号时,输入放宽了焦点。但是,只有当所有逻辑都在内部函数内部时。当使用按钮输入和逻辑在不同的文件中 - 它正在工作。我真的不知道为什么...

我已经创建了具有相同代码的单独文件并将其导入到索尔特 - 没关系。我已经尝试使用onChange = {handlechange} - 丢失的焦点。

export default function MyInput(){
const [citySearch, updateCitySearch] = useState();
function searchCityClick(){
   alert(citySearch);
}
const SearchComponent = ()=> (
    <div> 
        <input 
        value={citySearch}
        onChange={(e) => updateCitySearch(e.target.value)}/>
        <Button variant="contained" color="primary" onClick={searchCityClick}>
            Search
        </Button>
    </div>
);
return(
    <div>
        <div>
            <SearchComponent />
        </div>
    </div>
)}

SearchComponent是功能组件,不应在另一个组件内定义。在MyInput内定义SearchComponent将导致SearchComponent重新创建(未录制(,从本质上讲,它将被删除,然后在每次点击时添加。

该解决方案非常简单,从MyInput提取SearchComponent,然后通过props对象传递函数以及数据:

const { useState, useCallback } = React;
const SearchComponent = ({ citySearch, updateCitySearch, searchCityClick }) => (
  <div> 
    <input
      value={citySearch}
      onChange={e => updateCitySearch(e.target.value)} />
    
    <button onClick={searchCityClick}>Search</button>
  </div>
);
const MyInput = () => {
  const [citySearch, updateCitySearch] = useState('');
  const searchCityClick = () => alert(citySearch);
  return(
    <div>
      <SearchComponent 
        citySearch={citySearch} 
        updateCitySearch={updateCitySearch}
        searchCityClick={searchCityClick} />
    </div>
  );
};
ReactDOM.render(
  <MyInput />,
  root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

我也是新手反应重新渲染..

如果您使用 SearchComponent作为变量,而不是匿名函数,则可以按预期工作。

我也很好奇为什么使用这样的嵌套函数(当使用JSX时(会导致这种行为...可能是抗模式?

function MyInput() {
  const [citySearch, updateCitySearch] = React.useState();
  function searchCityClick() {
    alert(citySearch);
  }
  
  const SearchComponent = (
      <div> 
          <input 
          value={citySearch}
          onChange={(e) => updateCitySearch(e.target.value)}/>
          <button variant="contained" color="primary" onClick={searchCityClick}>
              Search
          </button>
      </div>
  );
  
  return (
    <div>
      <div>
        {SearchComponent}
      </div>
    </div>
  );
}
let div = document.createElement("div");
div.setAttribute("id", "app");
document.body.append(div);
ReactDOM.render(<MyInput />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

即使将嵌套函数更改为"实际组件",每个按键之后却丢失了焦点(又称OnChange(。

不起作用:

function MyInput() {
  const [citySearch, updateCitySearch] = React.useState();
  function searchCityClick() {
    alert(citySearch);
  }
  const SearchComponent = () => {
      return (
        <div> 
            <input 
            value={citySearch}
            onChange={(e) => updateCitySearch(e.target.value)}/>
            <button variant="contained" color="primary" onClick={searchCityClick}>
                Search
            </button>
        </div>
    );
  }
  return (
    <div>
      <div>
        <SearchComponent />
      </div>
    </div>
  );
}

发生这种情况,因为useState钩子不是"挂钩"到您的SearchComponent,而是您的MyInput组件。每当您调用updateCitySearch()时,您都会更改MyInput的状态,从而将 thote 组件强制重新渲染。

SearchComponent,在MyInput内明确定义。当更新citySearch-state时,SearchComponent失去焦点,因为周围的初始virual DOM不再完整,而是您拥有全新的DOM部分。本质上,您每次通过州更新MyInput时都会创建全新的SearchComponent

考虑以下示例:

function App() {
  const [citySearch, updateCitySearch] = useState("");
  console.log("rendered App again"); //always prints
  const SearchComponent = () => {
    console.log("rendered Search"); //always prints
    const searchCityClick = () => {
      alert(citySearch);
    };
    return (
      <div>
        <input
          value={citySearch}
          onChange={e => {
            updateCitySearch(e.target.value);
          }}
        />
        <button onClick={searchCityClick}>Search</button>
      </div>
    );
  };
  return (
    <div>
      <div>
        <SearchComponent />
      </div>
    </div>
  );
}

每次更新状态时,您都会触发console.log(),APP组件重新订阅和SearchComponent都会重新创建。每次都会渲染myInput的新迭代,并创建一个新的SearchComponent

但是,如果您要在SearchComponent内定义useState,则在状态更改时只有SearchComponent会重新渲染,因此将原始的myInput组件保持不变,并且当前SearchComponent完整。

function App() {
  console.log("rendered App again"); //would never print a 2nd time.
  const SearchComponent = () => {
    const [citySearch, updateCitySearch] = useState("");
    console.log("rendered Search"); //would print with new state change
    const searchCityClick = () => {
      alert(citySearch);
    };
    return (
      <div>
        <input
          value={citySearch}
          onChange={e => {
            updateCitySearch(e.target.value);
          }}
        />
        <button onClick={searchCityClick}>Search</button>
      </div>
    );
  };
  return (
    <div>
      <div>
        <SearchComponent />
      </div>
    </div>
  );
}

相关内容

  • 没有找到相关文章

最新更新