【问题标题】:Can we make changes on screen/browser without using hooks in ReactJS. (In case of functional component)?我们可以在不使用 ReactJS 中的钩子的情况下在屏幕/浏览器上进行更改吗? (如果是功能组件)?
【发布时间】:2021-06-25 11:12:38
【问题描述】:

我创建了一个切换按钮,它将显示和隐藏 value 变量。但是我看不到屏幕上的变化,虽然控制台显示'show'的值在我每次单击'Change Me'按钮时都会发生变化。

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>
  )
}

我对功能组件的理解是它们是无状态组件,我们只能呈现它们的状态/道具。这就是我无法创建没有钩子来呈现更改的切换按钮的原因吗?如果我错了,请纠正我或添加您的答案/想法以清除我的概念。

PS:我是 React 和学习 React 概念的新手。所以,这可能是一个愚蠢的问题。

【问题讨论】:

  • 为什么要写一个有状态的函数组件而不使用钩子?
  • @T.J.Crowder 如果有人不知道钩子的概念,肯定会想到这种事情。我希望你得到我。
  • 我很高兴你理解正确:如果你不使用钩子,它们是无状态的。 :-)

标签: javascript reactjs react-functional-component


【解决方案1】:

我对功能组件的理解是它们是无状态组件,我们只能呈现它们的状态/道具。这就是我无法创建没有钩子来呈现更改的切换按钮的原因吗?

是的。如果不使用钩子,函数组件是无状态的。要拥有一个有状态的组件,可以:

  • 使用挂钩,或
  • 改用class 组件

请注意,函数组件可以有 props 而不使用钩子(通常会这样做)。道具基本上是父元素管理的状态。父组件甚至可以将它调用的函数传递给您的函数组件,以响应可能使父组件更改函数组件使用的道具的事件(通过钩子或class 组件在父组件中使用状态)。但 props 与 state 不同。

例如,这是一个由父级更新的具有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>

【讨论】:

  • 您也可以使用 React 的 Context 将钩子作为道具传递。然后您可以调用该函数来更新上下文中的状态值。然后将呈现更改,并且您的组件仍然是无状态的..
  • @Raythe - “你也可以使用 React 的 Context 将钩子作为道具传递给它。” 那就是使用钩子。 :-)
  • 所以,基本上你的意思是,在父组件中,我可以使用钩子对状态进行更改,并将该状态作为道具传递给功能组件,并且每次状态更改时都会发生相同的更改反映在使用道具的功能组件中。正确的? @T.J.克劳德
  • 没错。 const [foo, setFoo] = React.useState();
  • @JayantSharma - 对,没错。状态(在 React 术语中)由组件本身管理(功能组件只能通过钩子来做到这一点),道具由父级管理。当 parent 改变 props 时,调用子组件根据新的 props 更新自身。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-16
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
相关资源
最近更新 更多