Реакция: Компонент только с формой, действие отправки формы отличается в зависимости от потребителя компонента - PullRequest
0 голосов
/ 16 января 2020

У меня есть React Component, который отображает простую форму поиска. Я использую «Контролируемые компоненты» (https://reactjs.org/docs/forms.html), чтобы компонент React сохранял критерии поиска и являлся источником истины.

class SearchForm extends React.Component {    

    constructor(props) {
        super(props);
        this.state = {criteria: ''};    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({criteria: event.target.value});
    }

    handleSubmit(event) {
        event.preventDefault();
        // only submit the search if there is search criteria
        if (this.state.criteria.length > 0){
            // I need to be able to set some state here
            this.setState({
                   .....
            });
            // i also need to access this.props here
            if (this.props......) ...
        }
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit} >

                <input type="text" 
                       placeholder="Search"
                       value={this.state.criteria} 
                       onChange={this.handleChange} />

                <button ...... />
            </form>
        );
    }
}

Я хочу использовать эту форму поиска в 2 места.

  • Поле поиска в заголовке: при отправке формы оно перенаправляет на другую страницу в моем приложении
  • Поле поиска на странице поиска: при отправке формы обновляется список поиска ниже форма поиска

Поэтому метод onSubmit в SearchForm не может иметь код для отправки в onForm, так как этот код будет различаться в зависимости от использования SearchForms.

Я знаю, как добавить поиск форма в моих компонентах HTML, например, в методе рендеринга Component1 у меня будет

<div>
    <SearchForm />
</div>

Однако я не знаю, как обрабатывать SearchForms onSubmit по-разному для каждого компонента, который использует форму поиска. Похоже, я хочу, чтобы onSubmit SearchForm вызывал метод в содержащем компоненте, передавая значение stateFcriteria SearchForm

Как я могу повторно использовать компонент SearchForm в других компонентах, которые имеют разные действия при отправке формы?

Ответы [ 3 ]

1 голос
/ 16 января 2020

Я думаю, вы можете преобразовать форму поиска в компонент функции и передать обработчик отправки в качестве реквизита. Использование Hooks будет идеальным выбором здесь.


 import React, { useState } from "react";

    export function SearchForm(props) {
      const [search, setInput] = useState('');

      const handleSubmit = (evt) => {
          evt.preventDefault();
          //validation here
         props.onSubmit(search)
      }
      return (
        <form onSubmit={this.handleSubmit}>
         <input
          type="text"
           placeholder="Search"
           value={search}
           onChange={(event) => setInput(event.target.value)}
        />

   <button/>
</form>;

      );
    }

, а затем вы можете использовать эту форму поиска в компоненте с желаемым действием при отправке, например.

import React, { Component } from 'react'
import { Text, View } from 'react-native'

import React, { Component } from 'react'

export default class Header extends Component {

  constructor(props){
     super(props)
     this.state = {whatever: ''}
     this.onSearch = this.onSearch.bind(this)
   }

  onSearch(value){
   //you logic to navigate or display searched items
  }
  render() {
    return (
      <div>
        <SearchForm onSubmit={this.onSearch}>
      </div>
    )
  }
}


Надеюсь, это поможет.

1 голос
/ 16 января 2020

Вы должны передать функцию обратного вызова вашему компоненту как props, например:


class SearchForm extends React.Component {    

    constructor(props) {
        super(props);
        this.state = {criteria: ''};    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({criteria: event.target.value});
    }

    handleSubmit(event) {
        event.preventDefault();
        // only submit the search if there is search criteria
        if (this.state.criteria.length > 0){
            this.props.onFormSubmit()
        }
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit} >

                <input type="text" 
                       placeholder="Search"
                       value={this.state.criteria} 
                       onChange={this.handleChange} />

                <button ...... />
            </form>
        );
    }
}

И использование компонента:

<div>
  <SearchForm onFormSubmit={this.handleFormSubmit} />
</div>
0 голосов
/ 16 января 2020

Я добавляю дополнительную информацию здесь, так как мне нужно было сделать дополнительные вещи, чтобы мой код работал.

Ответы, приведенные выше, ответили на мой вопрос, но я должен был сделать некоторые дополнительные действия для содержащихся компонентов, чтобы сделать так, как мне нужно, например,

  • доступ к «this» в компонентах, когда SearchForm вызывает обратный вызов (т. е. метод handleFormSubmit компонентов)
  • отображает начальное значение в поле ввода SearchForm в одном из случаев (то есть на странице результатов поиска показывают критерии, переданные ему)

Повторно используемый компонент, определенный как функция с крючками (https://reactjs.org/docs/hooks-intro.html)

import React, { useState } from 'react';

export default function SearchForm (props) {   

    // if a value was passed into this component, use it as the initial search criteria
    const [searchCriteria, setSearchCriteria] = useState(props.value ? props.value : '');

    const handleSubmit = (evt) => {
        evt.preventDefault();

        if (searchCriteria.length > 0){
            props.onFormSubmit(searchCriteria)
        }
    }

    return (
        <form onSubmit={handleSubmit}>

            <input type="text" 
                   value={searchCriteria}
                   onChange={(event) => setSearchCriteria(event.target.value)}/>

            <button />
        </form>
    );
}

Использование 1: Поле поиска в заголовок : при отправке формы она перенаправляется на «страницу результатов поиска»

import React from 'react';
import { withRouter} from 'react-router-dom';
import SearchForm from './SearchForm'

class SearchBox extends React.Component {

    componentDidMount() {
        // bind the SearchForm's callback method, so in "handleFormSubmit" we can use "this"
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
    }

    handleFormSubmit(criteria){
        this.props.history.push('/searchresultspage/'+ criteria)
    }

    render() {
        return (
            <SearchForm onFormSubmit={this.handleFormSubmit} />
        );
    }
}

// The following is needed so that the "this.props.history.push" in "handleSumbit" causes routing to happen
export default withRouter(SearchBox)

Использование 2: окно поиска на странице результатов поиска

  • при первом отображении страницы результатов поиска ее поле поиска должно содержать критерии поиска, переданные этой странице (т. Е. Из поля поиска в заголовке)
  • поиск должен быть выполнен и результаты отображаются
  • пользователь может изменить выполнить поиск в поле поиска и выполнить новый поиск

Код:

import React from 'react';

import SearchForm from './SearchForm'

export default class SearchResultsPage extends React.Component {

    state = {
        searchResults: [],
    }

    componentDidMount() {
        // bind the SearchForm's callback method, so in "handleFormSubmit" we can use "this"
        this.handleFormSubmit = this.handleFormSubmit.bind(this);

        this.performSearch(this.props.criteria);
    }

    handleFormSubmit(criteria){
        this.performSearch(criteria)
    }

    performSearch(criteria) {
        // do whatever to do a search and get results (e.g. store in this.state.searchResults)
    }


    render() {
        return (
            <div>
                {/* Pass the initial search criteria to the search form */}
                <SearchForm value={this.props.criteria} onFormSubmit={this.handleFormSubmit} />

                {/* do whatever to display the "this.state.searchResults */}
            </div>
        );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...