如何使用 useState - 钩子将类组件(输入,条件)更改为功能组件?

Posted

技术标签:

【中文标题】如何使用 useState - 钩子将类组件(输入,条件)更改为功能组件?【英文标题】:How to change a class component (input, conditional) to functional component with useState - hook? 【发布时间】:2020-01-23 11:48:54 【问题描述】:

我想将工作类组件更改为功能组件。它基本上是一个输入字段,应该:

1) 动态显示/镜像您输入的任何内容(参见表格下方的 h1) 2) 如果没有输入,则显示“未提供数据”

错误消息显示“编译失败...意外使用“事件””

import React,  useState  from "react"

function Exercise2() 
    const [input, inputChange] = useState(firstName: "")

    const handleChange = () => 
        inputChange([event.target.name]: event.target.value);
    

    let display
    if (useState.firstName != "") 
        display = useState.firstName
     else 
        display = "no data provided!"
    

    return (
        <div>
            <form>
                <input
                    type="text"
                    name="firstName"
                    placeholder="Enter your data here"
                    value = "input.firstName"
                    onChange = "handleChange"
                />
            </form>

            <h1>display</h1>
        </div>
    )


export default Exercise2

有人能指出我遗漏的东西吗(不要过多地改变代码结构,因为我想坚持我的初学者逻辑)。谢谢

PS:这是我的课程组件,效果很好,我正在尝试翻译

class Exercise1 extends React.Component 

    constructor() 
        super()
        this.state = 
            firstName:""
        
        this.handleChange = this.handleChange.bind(this)
    

    handleChange (event) 
        this.setState(
            [event.target.name]: event.target.value
        )
    

    render() 
        let display
        if(this.state.firstName != "") 
            display=this.state.firstName
         else 
            display="no data provided!"
        
        return (
            <div>
                <form>Input: 
                    <input 
                        type="text" 
                        name="firstName" 
                        placeholder = "Enter your data here!"
                        value=this.state.firstName
                        onChange=this.handleChange
                    />
                </form>

                <h1>display</h1>              
            </div>
        )
    

【问题讨论】:

您缺少event 参数:const handleChange = (event) =&gt; @Andy 将此部分更新为此但仍无法正常工作handleChange (event) =&gt; this.setState( [event.target.name]: event.target.value ) 【参考方案1】:

所以,关键是:

1) 不要将变量/方法名称放在花括号中

value=input.firstName
onChange=handleChange

2) 在您的 handleChange 方法中不包括 event 参数:

const handleChange = (event) => 

在这里,我已经纠正了这些问题,并更改了显示的渲染方式,使其更加“类似 React”。

const  useState  = React;

function Exercise2() 

  // Here you're setting state and assigning an object to it with
  // once property: `firstName`
  const [ input, inputChange ] = useState( firstName: '' );

  const handleChange = (event) => 

    // The click event has been passed in.
    // `target` is the element that's been clicked. We're just grabbing the name and
    // value from it. We're assigning the name `firstName` as a dynamic property key name
    // (we wrap it in square braces), and assign the value to it. We do that because we want to
    // update the `firstName` property in the state object.
    // Because state is an object (and we might eventually have other properties in there
    // that we want to keep when we update this value) we return an object containing all
    // the properties of input, and the new dynamic property
    inputChange( ...input, [event.target.name]: event.target.value );
  

  // `input` is an object with a firstName property.
  // We can destructure the `firstName` property from the state to make
  // it easier to work with
  const  firstName  = input;
console.log(input)
  let display;

  if (firstName.length) 
    display = firstName;
   else 
    display = "no data provided!";
  

  return (
    <div>
      <form>
        <input
          type="text"
          name="firstName"
          placeholder="Enter your data here"
          value=firstName
          onChange=handleChange
        />
      </form>

      <h1>display</h1>
    </div>
  );


ReactDOM.render(<Exercise2 />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"/>

【讨论】:

嘿@Andy ...这行得通。几个问题才能真正理解您所做的事情: 1. 为什么我必须将变量/方法放在大括号中,而在我不需要的类组件中? 2. const firstName = input 究竟是什么?做? 3.你能插入(注释掉)if else语句而不是onliner吗?谢谢 1)。您确实在花括号 (onChange=this.handleChange, for example) 中有方法/变量名称,并且 2) 那是 destructuring,并允许您更轻松地从对象和数组中提取数据。 我在代码中添加了一些注释@Stephan-thecurious 您使用了input.firstName,这很好,并且是访问该属性的传统方式。解构只是允许您访问该属性并将其分配给它自己的变量。它只是节省打字。 Here's your code without the destructuring. 感谢您的努力和时间。非常感谢您【参考方案2】:
import React,  useState  from "react"

function Exercise2() 
const [input, inputChange] = useState(firstName: "")

const handleChange = (event) => 
    inputChange([event.target.name]: event.target.value);


let display
if (input.firstName !== "") 
    display = input.firstName
 else 
    display = "no data provided!"


return (
    <div>
        <form>
            <input
                type="text"
                name="firstName"
                placeholder="Enter your data here"
                value = display
                onChange = handleChange
            />
        </form>

        <h1>display</h1>
    </div>
)


export default Exercise2

【讨论】:

那行不通。它既不反映我的条目,也不显示“未提供数据” 我改了代码,看到你的评论后才看到useState的用法抱歉。你现在可以检查吗? 关闭,但现在“没有提供数据!”也作为占位符而不是占位符“在此处输入您的数据” 那么我们应该从表​​单中删除 value = display。【参考方案3】:

你的语法似乎是错误的,你应该尝试类似

import React,  useState  from "react"

function Exercise2() 
    const [formData, changeFormData] = useState(firstName: "");

    const handleChange = (event) => 
        changeFormData([event.target.name]: event.target.value);
    



    return (
        <div>
            <form>
                <input
                    type="text"
                    name="firstName"
                    placeholder="Enter your data here"
                    value=formData.firstName
                    onChange=handleChange
                />
            </form>
            <h1>formData.firstName !== "" ? formData.firstName : 'no data provided!'</h1>
//the above line is a ternary operator, basically it reads as if( input.firstName !== "") return input.firstName : else return 'no data provided!'
        </div>
    )


export default Exercise2

【讨论】:

它不起作用。有一个输入字段,但在输入/没有输入时它既不镜像也不显示丢失的数据消息 对不起@Stephan-thecurious 我现在已经更新了,显然你不能使用输入作为状态,因为它是一个私有的 JS 变量,我把它改成了 formData 它现在应该可以工作了 我还建议您在状态更新函数中传播当前状态,因此如果您有其他字段,例如电子邮件或密码,它不会改变整个状态,例如 ``` changeFormData(. ..formdata, [event.target.name]: event.target.value) ``` 这基本上意味着如果formData发生了变化,保持其余未更改的数据并更改新的

以上是关于如何使用 useState - 钩子将类组件(输入,条件)更改为功能组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何编写依赖于 React 中 useState 钩子的条件渲染组件的测试?

反应钩子 useState 不使用 onSubmit 更新

使用 useState() 钩子测试功能组件时设置状态

如何在反应中使用带有useState钩子的回调[重复]

使用钩子将类组件转换为函数式

是否可以使用 React 中的 useState() 钩子在组件之间共享状态?