【问题标题】:Update other component on input value change React在输入值更改时更新其他组件 React
【发布时间】:2020-12-25 14:46:14
【问题描述】:

我正在学习 React,我正在尝试根据输入值更新一个组件。我已经使用 html 和 vanilla JavaScript 完成了这项工作,并且可以正常工作。我正在尝试使用 React 实现相同的功能,但我遇到了一些挑战。

这是我在原版 javascript 中的代码:

index.html

<!DOCTYPE html>
<html lang="en">

    <body>
        <div>
            <div>
                <div>
                    <h2>Press button when you are ready to play</h2>
                    <input type="text" placeholder="Start typing..." id="word-input" autofocus>
                </div>
            </div>
        </div>

        <script src="script.js"></script>
    </body>

</html>

script.js

const wordInput = document.querySelector('#word-input');
const currentWord = document.querySelector('#current-word');


const words = [
    'rock', 'paper', 'scissors', 'play'
];

displayWord(words)

wordInput.addEventListener('input', matchWords);

function displayWord(word) {
    const Index = Math.floor(Math.random() * word.length);
    currentWord.textContent = word[Index];
};

// match words
function matchWords() {

    if(wordInput.value === currentWord.innerHTML) {
        displayWord(words); 
        wordInput.value = ''; 
    };
};

到目前为止,这是我在 React 中尝试过的:

import React, { Component, createRef } from 'react'

export class About extends Component {

    state = {
        words: [
            'rock', 'paper', 'scissors', 'play'
        ],
        current_input: 'Start...',
        current_word: 'break'
    }
    
    inputRef = createRef();

    displayWord = (word) => {

        const Index = Math.floor(Math.random() * word.length);
        let rword = word[Index];

        this.setState({
            current_word: rword
        })

    };
    
    matchWords = (e) => {
        
        this.setState({
            current_input: e.target.value
        })

        if(this.state.current_input === this.state.current_word) {

            this.displayWord(this.state.words); 

            this.setState({
                current_input: ''
            })

            this.inputRef.current.focus();
        };
    };

    render() {
        return (
                <div>
                    <div>
                        <div>
                            <h2 id="current-word">{this.state.current_word}</h2>
                            <input ref={this.inputRef}
                             placeholder='start ..' onChange={this.matchWords} type="text"  id="word-input" autoFocus />
                        </div>  
                    </div>
                </div>
        )
    }
}

export default About

它似乎工作。但是,问题是在我输入单词后它不会更新 - 我必须在看到新单词出现之前尝试删除输入框的内容。此外,它不会自动清除内容并自动聚焦在输入框上,以便我输入新单词。我想知道我缺少什么以及就最佳实践而言,这是使用 React 执行此类操作的最佳或“正确”方式。谢谢!

【问题讨论】:

  • 试着从你的输入中删除那个 ref 东西,因为我试过没有它,它对我来说很好
  • 是的,但它仍然不会自动更新当前单词,清除输入字段并将光标聚焦在该字段上。 ref 是在调用displayWords 之后我如何将光标聚焦在输入字段上。除非有其他方法可以不使用ref

标签: javascript reactjs


【解决方案1】:

我认为,您应该在函数 matchWords 中更改代码,如下所示:

  matchWords = (e) => {
    if (e.target.value === this.state.current_word) {
      this.displayWord(this.state.words);

      this.setState({
        current_input: ""
      });

      this.inputRef.current.focus();
    } else {
      this.setState({
        current_input: e.target.value
      });
    }
  };

它不会像您期望的那样立即运行,因为setState 异步运行,当比较if (this.state.current_input === this.state.current_word) 时,当前输入是旧值。就像当你输入break 时比较是if ('brea' === 'break')

【讨论】:

    【解决方案2】:

    class About extends Component {
      state = {
        tmp: "",
        words: ["rock", "paper", "scissors", "play"],
        current_input: "",
        current_word: "break"
      };
    
      inputRef = createRef();
    
      displayWord = (word) => {
        const Index = Math.floor(Math.random() * word.length);
        let rword = word[Index];
    
        this.setState({
          current_word: rword
        });
      };
    
      matchWords = (e) => {
        this.setState({ current_input: e.target.value }, () => {
          if (this.state.current_input === this.state.current_word) {
            this.displayWord(this.state.words);
    
            this.setState({
              current_input: ""
            });
    
            this.inputRef.current.focus();
          }
        });
      };
    
      render() {
        return (
          <div>
            <div>
              <div>
                <h2 id="current-word">{this.state.current_word}</h2>
                <input
                  ref={this.inputRef}
                  value={this.state.current_input}
                  placeholder="start .."
                  onChange={(e) => this.matchWords(e)}
                  type="text"
                  id="word-input"
                  autoFocus
                />
              </div>
            </div>
          </div>
        );
      }
    }

    由于异步操作 current_input 状态更新没有最后一个字符。
    参考这个:onChange in React doesn't capture the last character of text
    您的代码的工作演示:https://codepen.io/navindu_d/pen/OJROmxN

    【讨论】:

      猜你喜欢
      • 2015-09-08
      • 2020-03-30
      • 2021-06-13
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多