我正在使用一个简单的无状态函数作为具有反应挂钩状态的反应组件。 另外,我想将每个函数放在单独的位置,以简化测试,并在函数变得更大时使代码更具可读性。
因此,在此示例中,handleChange
函数的作用应该比设置状态值还要多。
但是,如果我将其放在函数之外,则无法访问setMessage
函数和组件的支持。
这仍然有用吗?还是错误的反应方式?
example.js
import React, { useState } from 'react'
export function handleChange (event) = {
// do something...
// how to get props?
setMessage('new'); // is not defined at this place
}
export default function Message = (props) => {
const [message, setMessage] = useState('');
return (
<input
type="text"
value={message}
placeholder="Enter a message"
onChange={handleChange}
/>
);
};
答案 0 :(得分:2)
您可以为此使用curring
export const handleChange = setState => event => {
setState('new');
}
以及组件中的
export default function Message = (props) => {
const [message, setMessage] = useState('');
const reactOnChange = useCallback(handleChange(setMessage),[]);
return (
<input
type="text"
value={message}
placeholder="Enter a message"
onChange={reactOnChange }
/>
);
};
或者:
export const handleChange = relevantData => {
return 'new';
}
export default function Message = (props) => {
const [message, setMessage] = useState('');
return (
<input
type="text"
value={message}
placeholder="Enter a message"
onChange={e => setMessage(handleChange(getRelevantDataFrom(e)))}
/>
);
};
这使功能与反应完全分离。
函数内部的嵌套函数看起来不太好。如果您喜欢实用的方法,可以通过管道传递
onChange={pipe(getRelevantDataFrom, handleChange, setMessage)}
其中
const pipe = (...functions) => x => functions.reduce((acc, f) => f(acc), x)
答案 1 :(得分:1)
我可以看到并同意,将逻辑从组件中分离出来对测试很有益(尽管有时测试组件本身也很有价值,所以无论如何这都不是硬性规定)。
在您的情况下,我认为您正在尝试将线画得离React有点远。我的建议是在组件内部保留“ handleChange”,但在组件外部创建一个新函数,该函数处理您要隔离的逻辑,并在最后返回要设置的消息。该函数可以将props作为参数。因此,您的handleChange函数将使用相关的道具并将其作为参数传递给该函数,然后使用函数的返回值调用setMessage。现在,您具有可以测试的纯输入/输出功能。