React.useCallback() 用于链式匿名函数
React.useCallback() for chained anonymous functions
通常,为了将 onChange
回调函数传递给组件,您需要执行以下操作:
const handleChange = (e) => {
console.log(e.target.value)
}
return (
<Component onChange={handleChange} />
)
如果您不希望 Component
每次主组件都渲染,您必须将其包装在 React.useCallback()
钩子中,如下所示:
const handleChange = React.useCallback((e) => {
console.log(e.target.value)
}, [])
return (
<Component onChange={handleChange} />
)
如果此输入是在基于列表的 for 循环中生成的,您希望回调了解更改的来源。传递信息的最常见方式是按如下方式链接 lambda:
const fields = ['field1', 'field2', 'field3']
const handleChange = (fieldName) => (e) => {
console.log(`${fieldName}: `, e.target.value)
}
return (
<>
{fields.map((x) => <Component onChange={handleChange(x)} />}
</>
)
但在这种情况下,在使用 React.useCallback()
钩子将整个上下文保留在函数中的同时记忆外部和内部 lambda 是有点不可能的。
在大多数情况下,我可以控制组件并更改回调以包含所需的数据,但通常情况下组件来自库 (i.g。Material-UI),因此无法修改。
如何使用 React Hooks 完全记住此回调?
我如何处理这个问题是创建一个 state
并将其作为依赖项传递给 useCallback
挂钩,例如:
const [fields, setFields] = useState({'field1': "", 'field2': "", 'field3': ""});
const handleChange = React.useCallback((e) => {
console.log(`${fieldName}: `, e.target.value);
if(e.target.id === "field1") {
let newFields = {...fields};
fields.field1 = e.target.value;
setFields(newFields);
}
}, [fields])
return (
<>
{fields.map((x) => <Component onChange={handleChange(x)} />}
</>
)
希望这对你有用。
您可以为每个元素生成事件处理程序,并记忆事件处理程序数组。创建元素时,通过其索引获取相关事件处理程序:
const { memo, useMemo } = React
const Demo = ({ fields }) => {
const handlers = useMemo(() =>
fields.map(fieldName => e => {
console.log(`${fieldName}: `, e.target.value)
})
, [fields])
return (
<div>
{
fields.map(
(fieldName, i) => (
<input key={fieldName} onChange={handlers[i]} />
))
}
</div>
)
}
const fields = ['field1', 'field2', 'field3']
ReactDOM.render(
<Demo fields={fields} />,
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>
通常,为了将 onChange
回调函数传递给组件,您需要执行以下操作:
const handleChange = (e) => {
console.log(e.target.value)
}
return (
<Component onChange={handleChange} />
)
如果您不希望 Component
每次主组件都渲染,您必须将其包装在 React.useCallback()
钩子中,如下所示:
const handleChange = React.useCallback((e) => {
console.log(e.target.value)
}, [])
return (
<Component onChange={handleChange} />
)
如果此输入是在基于列表的 for 循环中生成的,您希望回调了解更改的来源。传递信息的最常见方式是按如下方式链接 lambda:
const fields = ['field1', 'field2', 'field3']
const handleChange = (fieldName) => (e) => {
console.log(`${fieldName}: `, e.target.value)
}
return (
<>
{fields.map((x) => <Component onChange={handleChange(x)} />}
</>
)
但在这种情况下,在使用 React.useCallback()
钩子将整个上下文保留在函数中的同时记忆外部和内部 lambda 是有点不可能的。
在大多数情况下,我可以控制组件并更改回调以包含所需的数据,但通常情况下组件来自库 (i.g。Material-UI),因此无法修改。
如何使用 React Hooks 完全记住此回调?
我如何处理这个问题是创建一个 state
并将其作为依赖项传递给 useCallback
挂钩,例如:
const [fields, setFields] = useState({'field1': "", 'field2': "", 'field3': ""});
const handleChange = React.useCallback((e) => {
console.log(`${fieldName}: `, e.target.value);
if(e.target.id === "field1") {
let newFields = {...fields};
fields.field1 = e.target.value;
setFields(newFields);
}
}, [fields])
return (
<>
{fields.map((x) => <Component onChange={handleChange(x)} />}
</>
)
希望这对你有用。
您可以为每个元素生成事件处理程序,并记忆事件处理程序数组。创建元素时,通过其索引获取相关事件处理程序:
const { memo, useMemo } = React
const Demo = ({ fields }) => {
const handlers = useMemo(() =>
fields.map(fieldName => e => {
console.log(`${fieldName}: `, e.target.value)
})
, [fields])
return (
<div>
{
fields.map(
(fieldName, i) => (
<input key={fieldName} onChange={handlers[i]} />
))
}
</div>
)
}
const fields = ['field1', 'field2', 'field3']
ReactDOM.render(
<Demo fields={fields} />,
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>