asl*_*rai 8 javascript reactjs react-hooks
在基于类的React组件中,我做这样的事情:
class SomeComponent extends React.Component{
onChange(ev){
this.setState({text: ev.currentValue.text});
}
transformText(){
return this.state.text.toUpperCase();
}
render(){
return (
<input type="text" onChange={this.onChange} value={this.transformText()} />
);
}
}
Run Code Online (Sandbox Code Playgroud)
为了简化我的观点,这是一个人为的示例。我本质上想要做的是保持对onChange函数的恒定引用。在上面的示例中,当React重新渲染我的组件时,如果输入值未更改,它将不会重新渲染输入。
这里要注意的重要事项:
现在,如果我要使用钩子重写此组件,请执行以下操作:
function onChange(setText, ev) {
setText(ev.currentValue.text);
};
function transformText(text) {
return text.toUpperCase();
};
function SomeComponent(props) {
const [text, setText] = useState('');
return (
<input type="text" onChange={onChange} value={transformText()} />
);
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是,我需要传递text
到transformText
和setText
到onChange
分别的方法。我能想到的可能解决方案是:
进行上述任何一项操作都会更改对我需要维护的功能的常量引用,以便不input
重新渲染组件。我该如何使用挂钩?可能吗
请注意,这是一个非常简化的人为示例。我的实际用例非常复杂,我绝对不想不必要地重新渲染组件。
编辑:这不是React中useCallback做什么的重复项?因为我试图找出如何实现与类组件方式相似的效果,并且尽管useCallback
提供了一种实现方式,但对于可维护性问题而言,它并不是理想的选择。
在组件函数中定义函数,并使用闭包传递值。然后,您正在寻找的是useCallback
避免不必要的重新渲染。(对于此示例,它不是很有用)
function SomeComponent(props) {
const [text, setText] = useState('');
const onChange = useCallback((ev) => {
setText(ev.target.value);
}, []);
function transformText(text) {
return text.toUpperCase();
};
return (
<input type="text" onChange={onChange} value={transformText(text)} />
);
}
Run Code Online (Sandbox Code Playgroud)
在这里阅读更多
在这里您可以构建自己的钩子(Dan Abramov敦促不要使用“自定义钩子”一词,因为它会使创建自己的钩子比原来更难/更高级,这只是复制/粘贴您的逻辑)提取文本转换逻辑
只需从Mohamed的答案中 “剪切”下面注释掉的代码即可。
function SomeComponent(props) {
// const [text, setText] = React.useState("");
// const onChange = ev => {
// setText(ev.target.value);
// };
// function transformText(text) {
// return text.toUpperCase();
// }
const { onChange, text } = useTransformedText();
return (
<input type="text" onChange={React.useCallback(onChange)} value={text} />
);
}
Run Code Online (Sandbox Code Playgroud)
并将其粘贴到新函数中(按照惯例,前缀为“ use *”)。命名状态和回调以返回(根据您的情况作为对象或数组)
function useTransformedText(textTransformer = text => text.toUpperCase()) {
const [text, setText] = React.useState("");
const onChange = ev => {
setText(ev.target.value);
};
return { onChange, text: textTransformer(text) };
}
Run Code Online (Sandbox Code Playgroud)
由于可以传递转换逻辑(但默认情况下使用UpperCase),因此可以使用自己的钩子使用共享逻辑。
function UpperCaseInput(props) {
const { onChange, text } = useTransformedText();
return (
<input type="text" onChange={React.useCallback(onChange)} value={text} />
);
}
function LowerCaseInput(props) {
const { onChange, text } = useTransformedText(text => text.toLowerCase());
return (
<input type="text" onChange={React.useCallback(onChange)} value={text} />
);
}
Run Code Online (Sandbox Code Playgroud)
您可以像下面这样使用上面的组件。
function App() {
return (
<div className="App">
To Upper case: <UpperCaseInput />
<br />
To Lower case: <LowerCaseInput />
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
结果看起来像这样。
归档时间: |
|
查看次数: |
4428 次 |
最近记录: |