【问题标题】:Cannot write into the input field in React App无法写入 React App 中的输入字段
【发布时间】:2020-04-13 09:50:06
【问题描述】:

每当我尝试启动应用程序时,我都无法在输入字段中写入任何内容。可能是因为 react 正在重新渲染某些组件,因为我在每次点击时调用 setState。

父 App.js 包含一个具有输入字段的 SearchForm。每当在输入字段中输入数据时,我都会调用处理程序来设置状态,以便在单击按钮时可以对 API 进行提取

这是我的 app.js 文件。

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import NavigationBar from './components/NavigationBar/NavigationBar.js';
import Logo from './components/Logo/Logo.js';
import SearchForm from './components/SearchForm/SearchForm.js';
import SearchFilter from './components/SearchFilter/SearchFilter.js';
import ReviewComponent from './components/ReviewComponent/ReviewComponent.js';


class App extends React.Component {
  constructor(){
    super();
    this.state = {
      searchfield: '', 
      searchresults: {}
    }
    this.onInputChange = this.onInputChange.bind(this);
    this.onSearchClick = this.onSearchClick.bind(this);
  }

  onInputChange = (event) => {
    this.setState({searchfield: event.target.value});
  }

  onSearchClick = () => {
    fetch('https://maps.googleapis.com/maps/api/place/findplacefromtext/json?key=&inputtype=textquery&type=restaurant&input=kfc&fields=name,place_id,formatted_address')
      .then(response=> response.json())
      .then(results => {this.setState({ searchresults: results})})
      .then(results => {console.log("lulli" + JSON.stringify(this.state.searchresults))});
  }

  render(){
    return (
      <div className="App">
        <BrowserRouter> {/* using react-router-dom for routing */}
          <NavigationBar />  {/* for navigation through the app, always rendered */}
          <Logo />   {/* a logo for the RestrauntReviewsTool */}
          <Switch>
            <Route path='/' 
              exact 
              component={() => <SearchForm onInputChange={this.onInputChange} onSearchClick={this.onSearchClick} /> } 
            />  
            <Route 
              path='/searchfilter' 
              component={() => <SearchFilter searchresults={this.searchresults} /> } 
            />  

            <ReviewComponent path='/reviewcomponent' component={ReviewComponent} /> {/* final restaurant details */}
          </Switch>
        </BrowserRouter>

      </div>
    );
  }
}


export default App;

这是我的 SearchForm.js

import React from 'react';
import {Link} from 'react-router-dom';

const SearchForm = ({ onInputChange, onSearchClick }) => {
    return(
        <div>
            <p className='f3'>
                {'Search here for restaurants, maybe make an api fetch here and populate data in the SearchFilter component'}
            </p>
            <div className='center'>
                <div className='form center pa4 br3 shadow-5'>
                    <input className='f4 pa2 w-70 center' type='text' onChange={onInputChange}/>
                    <button className='w-30 grow f4 ph3 pv2 dib white bg-light-purple' onClick={onSearchClick}>
                    <Link to ='/searchfilter'>
                    Search   
                    </Link>    
                    </button>

                </div>
            </div>
        </div>
    );
}

export default SearchForm;

【问题讨论】:

    标签: javascript reactjs react-router google-places-api


    【解决方案1】:

    您需要将 searchField 状态作为道具传递给子组件。

    在 SearchForm 组件中,您的输入需要具有 value={searchField}

    所以当你的 searchField 状态改变时子组件会重新渲染。

    class App extends React.Component {
      constructor(){
        super();
        this.state = {
          searchfield: '', 
          searchresults: {}
        }
        this.onInputChange = this.onInputChange.bind(this);
        this.onSearchClick = this.onSearchClick.bind(this);
      }
    
      onInputChange = (event) => {
        this.setState({searchfield: event.target.value});
      }
    
      onSearchClick = () => {
        fetch('https://maps.googleapis.com/maps/api/place/findplacefromtext/json?key=&inputtype=textquery&type=restaurant&input=kfc&fields=name,place_id,formatted_address')
          .then(response=> response.json())
          .then(results => {this.setState({ searchresults: results})})
          .then(results => {console.log("lulli" + JSON.stringify(this.state.searchresults))});
      }
    
      render(){
        return (
          <div className="App">
            <BrowserRouter> {/* using react-router-dom for routing */}
              <NavigationBar />  {/* for navigation through the app, always rendered */}
              <Logo />   {/* a logo for the RestrauntReviewsTool */}
              <Switch>
                <Route path='/' 
                  exact 
                  component={() => <SearchForm searchfield={this.state.searchfield} onInputChange={this.onInputChange} onSearchClick={this.onSearchClick} /> } 
                />  
                <Route 
                  path='/searchfilter' 
                  component={() => <SearchFilter searchresults={this.searchresults} /> } 
                />  
    
                <ReviewComponent path='/reviewcomponent' component={ReviewComponent} /> {/* final restaurant details */}
              </Switch>
            </BrowserRouter>
    
          </div>
        );
      }
    }
    
    
    export default App;

    import React from 'react';
    import {Link} from 'react-router-dom';
    
    const SearchForm = ({ searchField, onInputChange, onSearchClick }) => {
        return(
            <div>
                <p className='f3'>
                    {'Search here for restaurants, maybe make an api fetch here and populate data in the SearchFilter component'}
                </p>
                <div className='center'>
                    <div className='form center pa4 br3 shadow-5'>
                        <input className='f4 pa2 w-70 center' type='text' value={searchField} onChange={onInputChange}/>
                        <button className='w-30 grow f4 ph3 pv2 dib white bg-light-purple' onClick={onSearchClick}>
                        <Link to ='/searchfilter'>
                        Search   
                        </Link>    
                        </button>
    
                    </div>
                </div>
            </div>
        );
    }
    
    export default SearchForm;

    【讨论】:

    • 这样做让我更接近,但并没有解决问题。组件重新渲染使光标从输入字段中消失,我必须再次单击它才能输入另一个字母。有什么办法解决这个问题?
    • 这里是仍然存在问题的视觉参考:github.com/facebook/react/issues/5554 但我找不到导致它的原因
    【解决方案2】:

    实际上,在 ReactJS 中,开发者除了控制 input 上的更改外,还应该控制 input 的值:

    handleInputChangeValue = e =>
      this.setState({
        inputValue: e.target.value
      });
    
    ~~~
    
    <input
      type="text"
      value={this.state.inputValue}
      onChange={this.handleInputChangeValue}
    />
    

    但是,在您的代码中,您只是处理了更改,并没有将新值传递给 input 标记:

    <input className='f4 pa2 w-70 center' type='text' onChange={onInputChange}/>
    

    【讨论】:

    • 按照您所说的,问题在一定程度上解决了,但我仍然遇到类似这里的问题:github.com/facebook/react/issues/5554
    • 亲爱的@AhmedSuhail,您的链接是另一个问题。当你得到答案时,在 Stack Overflow 上勾选它是正确的,然后留下另一个问题。这是一个正确的方法。
    猜你喜欢
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多