Reactjs 带条件反应挂钩的可选受控/非受控反应组件
在我看来,React-Hooks-useState非常适合模式选择使用props中的值或使用自己的状态,但是当我有条件地使用hook时,lint显示了一些错误 我尝试使用钩子,条件如下,但是使用eslint errorReactjs 带条件反应挂钩的可选受控/非受控反应组件,reactjs,react-hooks,Reactjs,React Hooks,在我看来,React-Hooks-useState非常适合模式选择使用props中的值或使用自己的状态,但是当我有条件地使用hook时,lint显示了一些错误 我尝试使用钩子,条件如下,但是使用eslint errorReact钩子useState被有条件地调用。根据这一点,React依赖于调用钩子的顺序 const Counter = ({ value, onChange, defaultValue = 0 }) => { const [count, onCountChange]
React钩子useState被有条件地调用。根据这一点,React依赖于调用钩子的顺序
const Counter = ({ value, onChange, defaultValue = 0 }) => {
const [count, onCountChange] =
typeof value === "undefined" ? useState(defaultValue) : [value, onChange];
return (
<div>
{count.toString()}
<button
onClick={() => {
onCountChange(count + 1);
}}
>
+
</button>
</div>
);
};
function App() {
const [count, onCountChange] = useState(0);
return (
<div className="App">
<div>
Uncontrolled Counter
<Counter />
</div>
<div>
Controlled Counter
<Counter value={count} onChange={onCountChange} />
</div>
</div>
);
}
const Counter=({value,onChange,defaultValue=0})=>{
常数[计数,计数变化]=
值的类型==“未定义”?使用状态(默认值):[value,onChange];
返回(
{count.toString()}
{
onCountChange(计数+1);
}}
>
+
);
};
函数App(){
const[count,onCountChange]=useState(0);
返回(
非受控计数器
受控计数器
);
}
如何使用钩子来实现与类下组件相同的功能
class CounterClass extends React.Component {
state = {
value: this.props.defaultValue || 0
};
render() {
const isControlled = typeof this.props.defaultValue === "undefined";
const count = isControlled ? this.props.value : this.state.value;
return (
<div>
{count.toString()}
<button
onClick={() => {
isControlled &&
this.props.onChange &&
this.props.onChange(this.props.value + 1);
!isControlled && this.setState({ value: this.state.value + 1 });
}}
>
+
</button>
</div>
);
}
}
类反类扩展了React.Component{
状态={
值:this.props.defaultValue | | 0
};
render(){
const isControlled=typeof this.props.defaultValue==“未定义”;
const count=isControlled?this.props.value:this.state.value;
返回(
{count.toString()}
{
控制&&
这个。道具。改变&&
this.props.onChange(this.props.value+1);
!isControlled&&this.setState({value:this.state.value+1});
}}
>
+
);
}
}
或者这种道具/状态可选方式在一个组件中是错误的
我从React JSX
组件中学习了“defaultValue”
,“value”
,“onChange”
API命名和思想。您可以将组件分为完全受控和完全不受控
const CounterRepresentation=({value,onChange})=>(
{value.toString()}
{
onChange(值+1);
}}
>
+
);
const Uncontrolled=({defaultValue=0})=>{
const[value,onChange]=使用状态(defaultValue);
返回;
};
//可以直接使用表示法,也可以不受控制地使用表示法
常量计数器=({value,onChange,defaultValue=0})=>{
返回值的类型==“未定义”(
) : (
);
};
好问题!我认为这可以通过钩子来解决,方法是使useState
调用成为无条件的,并且只使部分成为有条件的,在这里您可以决定渲染哪个状态以及使用什么更改处理程序
我刚刚释放了一个钩子,解决了这个问题:
用法:
import useOptionallyControlledState from 'use-optionally-controlled-state';
function Expander({
expanded: controlledExpanded,
initialExpanded = false,
onChange
}) {
const [expanded, setExpanded] = useOptionallyControlledState({
controlledValue: controlledExpanded,
initialValue: initialExpanded,
onChange
});
function onToggle() {
setExpanded(!expanded);
}
return (
<>
<button onClick={onToggle} type="button">
Toggle
</button>
{expanded && <div>{children}</div>}
</>
);
}
// Usage of the component:
// Controlled
<Expander expanded={expanded} onChange={onExpandedChange} />
// Uncontrolled using the default value for the `initialExpanded` prop
<Expander />
// Uncontrolled, but with a change handler if the owner wants to be notified
<Expander initialExpanded onChange={onExpandedChange} />
从“使用可选控制状态”导入使用可选控制状态;
函数扩展器({
扩展:控制扩展,
initialExpanded=false,
一旦改变
}) {
const[expanded,setExpanded]=使用可选的受控状态({
controlledValue:controlledExpanded,
initialValue:initialExpanded,
一旦改变
});
函数onToggle(){
setExpanded(!expanded);
}
返回(
切换
{扩展&&{children}}
);
}
//组件的使用:
//控制
//使用'initialExpanded'属性的默认值不受控制
//不受控制,但如果所有者希望得到通知,则使用变更处理程序
通过使用一个钩子来实现这一点,您不必包装一个额外的组件,理论上,您可以将其应用于同一组件中的多个道具(例如,一个
组件,其中两个道具都可以随意控制)。Wow!!我想这是我需要的正确答案。我认为这是一个使用代表性组件
和容器组件
(或智能/转储组件)概念的好例子。
import useOptionallyControlledState from 'use-optionally-controlled-state';
function Expander({
expanded: controlledExpanded,
initialExpanded = false,
onChange
}) {
const [expanded, setExpanded] = useOptionallyControlledState({
controlledValue: controlledExpanded,
initialValue: initialExpanded,
onChange
});
function onToggle() {
setExpanded(!expanded);
}
return (
<>
<button onClick={onToggle} type="button">
Toggle
</button>
{expanded && <div>{children}</div>}
</>
);
}
// Usage of the component:
// Controlled
<Expander expanded={expanded} onChange={onExpandedChange} />
// Uncontrolled using the default value for the `initialExpanded` prop
<Expander />
// Uncontrolled, but with a change handler if the owner wants to be notified
<Expander initialExpanded onChange={onExpandedChange} />