我们可以在不使用 ReactJS 中的钩子的情况下对 screen/browser 进行更改吗? (如果是功能组件)?
Can we make changes on screen/browser without using hooks in ReactJS. (In case of functional component)?
我创建了一个切换按钮,可以显示和隐藏值变量。但是我看不到屏幕上的变化,尽管控制台显示每次单击 'Change Me' 按钮时 'show' 的值都在变化。
import React from 'react'
export default function State(){
let val = 4;
let show = true;
function changeMe(){
show = !show;
console.log(show);
}
return(
<div>
{show ? <span>{val}</span> : null}
<br></br>
<button onClick = {changeMe}>Change Me</button>
</div>
)
}
我对函数式组件的理解是它们是无状态组件,我们只能展示它们中的state/props个。这就是我无法在没有钩子的情况下创建切换按钮来呈现更改的原因吗?如果我错了请纠正我或添加您的 answer/thought 以清除我的概念。
PS: 我是 React 的新手,正在学习 React 的概念。所以,这可能是一个愚蠢的问题。
What I understand about functional component is that they are stateless component and we can only present the state/props of them. Is this is the reason I can't create toggle button without hooks to render the changes.
是的。如果不使用钩子,函数组件就是无状态的。要拥有有状态组件,可以:
- 使用钩子,或者
- 改用
class
组件
请注意,函数组件可以有 props 而无需使用钩子(通常会这样做)。道具基本上是父元素管理的状态。父级甚至可以将它调用的函数传递给您的功能组件,以响应可能使父级组件更改功能组件使用的 prop 的事件(通过挂钩或 class
组件在父级中使用状态)。但是道具与状态不同。
例如,这里有一个由父更新的 ticks
属性 的函数组件:
const {Component, useState, useEffect} = React;
function Child({ticks}) {
return <div>{ticks}</div>;
}
class ClassParent extends Component {
constructor(props) {
super(props);
this.state = {
ticks: 0
};
this.onTick = this.onTick.bind(this);
}
componentDidMount() {
this.timer = setInterval(this.onTick, this.props.interval || 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
onTick() {
this.setState(({ticks}) => {
++ticks;
return {ticks};
});
}
render() {
return <Child ticks={this.state.ticks} />;
}
}
function FunctionParent({interval = 1000}) {
const [ticks, setTicks] = useState(0);
useEffect(() => {
const timer = setInterval(() =>{
setTicks(t => t + 1);
}, interval);
}, []);
return <Child ticks={ticks} />;
}
function Example() {
return <div>
<ClassParent interval={800} />
<FunctionParent interval={400} />
</div>;
}
ReactDOM.render(<Example/>, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
我创建了一个切换按钮,可以显示和隐藏值变量。但是我看不到屏幕上的变化,尽管控制台显示每次单击 'Change Me' 按钮时 'show' 的值都在变化。
import React from 'react'
export default function State(){
let val = 4;
let show = true;
function changeMe(){
show = !show;
console.log(show);
}
return(
<div>
{show ? <span>{val}</span> : null}
<br></br>
<button onClick = {changeMe}>Change Me</button>
</div>
)
}
我对函数式组件的理解是它们是无状态组件,我们只能展示它们中的state/props个。这就是我无法在没有钩子的情况下创建切换按钮来呈现更改的原因吗?如果我错了请纠正我或添加您的 answer/thought 以清除我的概念。
PS: 我是 React 的新手,正在学习 React 的概念。所以,这可能是一个愚蠢的问题。
What I understand about functional component is that they are stateless component and we can only present the state/props of them. Is this is the reason I can't create toggle button without hooks to render the changes.
是的。如果不使用钩子,函数组件就是无状态的。要拥有有状态组件,可以:
- 使用钩子,或者
- 改用
class
组件
请注意,函数组件可以有 props 而无需使用钩子(通常会这样做)。道具基本上是父元素管理的状态。父级甚至可以将它调用的函数传递给您的功能组件,以响应可能使父级组件更改功能组件使用的 prop 的事件(通过挂钩或 class
组件在父级中使用状态)。但是道具与状态不同。
例如,这里有一个由父更新的 ticks
属性 的函数组件:
const {Component, useState, useEffect} = React;
function Child({ticks}) {
return <div>{ticks}</div>;
}
class ClassParent extends Component {
constructor(props) {
super(props);
this.state = {
ticks: 0
};
this.onTick = this.onTick.bind(this);
}
componentDidMount() {
this.timer = setInterval(this.onTick, this.props.interval || 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
onTick() {
this.setState(({ticks}) => {
++ticks;
return {ticks};
});
}
render() {
return <Child ticks={this.state.ticks} />;
}
}
function FunctionParent({interval = 1000}) {
const [ticks, setTicks] = useState(0);
useEffect(() => {
const timer = setInterval(() =>{
setTicks(t => t + 1);
}, interval);
}, []);
return <Child ticks={ticks} />;
}
function Example() {
return <div>
<ClassParent interval={800} />
<FunctionParent interval={400} />
</div>;
}
ReactDOM.render(<Example/>, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>