繁体   English   中英

如何在React JS中使用onSubmit更改DOM?

[英]How to change DOM using onSubmit in React JS?

我正在使用react作为搜索应用程序的前端。

当用户提交查询并弹出结果列表时,每个用户都会显示一个“了解更多”的按钮。 按下“了解更多”按钮后,结果列表应全部消失,并替换为所选主题的信息。

上面的搜索栏应该保留在原位,如果用户搜索新信息,学习更多信息应该消失,并且应该出现新的结果列表。

我无法显示了解更多信息。

我遇到的最大问题是我必须使用带有onSubmit函数的表单,并且一旦调用onSubmit函数,我的结果将保持几秒钟,然后一切都将消失。

以下显示了与问题相关的文件部分

class Search extends React.Component {

 learnMore(obj){
   //Here is where i would like to replace the results class with the learn more info. obj.learnMore has the info stored
 }

 render() {
   return (
     <div className="search">
       <div className="search-bar">
       // Here is where my search bar is, results of search get added to results array
       </div>

       <div className= "results">
       {this.state.results.map((obj) =>
         <div key={obj.id}>
            <p> {obj.name} </p>
            <form id= "learn-more-form" onSubmit={() => {this.learnMore(obj); return false;}}>
               <input type="submit" value="Learn More"/>
           </form>
         </div>
       )}
       </div>

     </div>
   );
 }
}

你应该像这样做你的onSubmit:

<form id= "learn-more-form" onSubmit={this.learnMore(obj)}>
    <input type="submit" value="Learn More"/>
</form>

那么函数应该是:

learnMore = (data) => (e) => {
    e.preventDefault()
    console.log(data) // probably setState with this data so you can display it when it, like this.setState({ currentMoreResults: data })
}

有很多方法可以处理这种情况。 在这种情况下,我建议将容器与组件分开。 容器将处理所有state并相应地更新其子components

请注意,此示例使用了大量ES6语法。 请阅读以下内容以了解其中一些是如何工作的: 胖箭头函数ES6销毁扩展运算符三元运算符类属性利用事件处理程序和状态的受控反应形式数组过滤以及使用PropTypes进行类型检查

这需要很多,所以如果您有任何问题,请随时提出。

工作范例

编辑搜索用户


集装箱/ SeachForm

import React, { Component } from "react";
import moment from "moment";
import LearnMore from "../../components/LearnMore";
import Results from "../../components/Results";
import SearchBar from "../../components/Searchbar";

const data = [
  {
    id: "1",
    name: "Bob",
    age: 32,
    email: "bob@example.com",
    registered: moment("20111031", "YYYYMMDD").fromNow(),
    description: "Bob is a stay at home dad."
  },
  {
    id: "2",
    name: "Jane",
    age: 43,
    email: "jane@example.com",
    registered: moment("20010810", "YYYYMMDD").fromNow(),
    description: "Jane is a CEO at Oracle."
  },
  {
    id: "3",
    name: "Yusef",
    age: 21,
    email: "yusef@example.com",
    registered: moment("20180421", "YYYYMMDD").fromNow(),
    description: "Yusef is a student at UC Berkeley."
  },
  {
    id: "4",
    name: "Dasha",
    age: 29,
    email: "dasha@example.com",
    registered: moment("20050102", "YYYYMMDD").fromNow(),
    description: "Dasha is an owner of a local antique shop."
  },
  {
    id: "5",
    name: "Polina",
    age: 18,
    email: "dasha@example.com",
    registered: moment("20190102", "YYYYMMDD").fromNow(),
    description: "Polina works at a local movie theather."
  }
];

const initialState = {
  searchQuery: "",
  results: data, // <== change this to an empty array if you don't want to show initial user data
  learnMore: false
};

class SearchForm extends Component {
  state = { ...initialState }; // spreading out the initialState object defined above; it'll be the same as: "state = { searchQuery: "",  results: data, learnMore: false }; " 

  handleSubmit = e => {
    e.preventDefault(); // prevents a page refresh

    if (!this.state.searchQuery) return null; // prevents empty search submissions

    this.setState({
      results: data.filter(
        person => person.name.toLowerCase() === this.state.searchQuery.toLowerCase()
      ) // filters the dataset with the "searchQuery" (lowercased names) and returns the result if it finds a match
    });
  };

  handleSearch = ({ target: { value } }) =>
    this.setState({ searchQuery: value }); // updates searchQuery input with an event.target.value 

  handleReset = () => this.setState({ ...initialState }); // resets to initial state

  handleLearnMore = person => {
    this.setState({ learnMore: true, results: person }); // sets learnMore to true (to show the "LearnMore" component) and sets results to the selected user
  };

  render = () => (
    <div className="container">
      <SearchBar
        handleReset={this.handleReset}
        handleSearch={this.handleSearch}
        handleSubmit={this.handleSubmit}
        searchQuery={this.state.searchQuery}
      />
      {!this.state.learnMore ? ( // if learnMore is false, then show "Results"
        <Results  
          results={this.state.results}
          handleLearnMore={this.handleLearnMore}
        />
      ) : (
        <LearnMore {...this.state.results} /> // otherwise, show LearnMore
      )}
    </div>
  );
}

export default SearchForm;

组件/搜索栏

import React from "react";
import PropTypes from "prop-types";

const SearchBar = ({
  handleReset,
  handleSearch,
  handleSubmit,
  searchQuery
}) => (
  <div className="search">
    <div className="search-bar">
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          className="uk-input"
          value={searchQuery}
          placeholder="Search for a name"
          onChange={handleSearch}
        />
        <div className="button-container">
          <button
            type="button"
            className="uk-button uk-button-danger reset"
            onClick={handleReset}
          >
            Reset
          </button>
          <button type="submit" className="uk-button uk-button-primary submit">
            Submit
          </button>
        </div>
      </form>
    </div>
  </div>
);

SearchBar.propTypes = {
  handleReset: PropTypes.func.isRequired,
  handleSearch: PropTypes.func.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  searchQuery: PropTypes.string
};

export default SearchBar;

组件/结果

import React from "react";
import PropTypes from "prop-types";

const Results = ({ handleLearnMore, results }) => (
  <div className="results">
    {results && results.length > 0 ? (
      results.map(person => (
        <div key={person.id} className="uk-card uk-card-default uk-width-1-2@m">
          <div className="uk-card-header">
            <div className="uk-width-expand">
              <h3 className="uk-card-title uk-margin-remove-bottom">
                {person.name}
              </h3>
            </div>
          </div>
          <div className="uk-card-body">
            <p>{person.description}</p>
          </div>
          <div className="uk-card-footer">
            <button
              onClick={() => handleLearnMore(person)}
              className="uk-button uk-button-text"
            >
              Learn More
            </button>
          </div>
        </div>
      ))
    ) : (
      <div className="uk-placeholder">No users were found!</div>
    )}
  </div>
);

Results.propTypes = {
  handleLearnMore: PropTypes.func.isRequired,
  results: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string,
      name: PropTypes.string,
      age: PropTypes.number,
      email: PropTypes.string,
      registered: PropTypes.string,
      description: PropTypes.string
    })
  )
};

export default Results;

组件/ LEARNMORE

import React from "react";
import PropTypes from "prop-types";

const LearnMore = ({ name, email, age, description, registered }) => (
  <div className="uk-card uk-card-default uk-card-body">
    <h3 className="uk-card-header">{name}</h3>
    <p>
      <strong>Email</strong>: {email}
    </p>
    <p>
      <strong>Registered</strong>: {registered}
    </p>
    <p>
      <strong>Age</strong>: {age}
    </p>
    <p>
      <strong>Job</strong>: {description}
    </p>
  </div>
);

LearnMore.propTypes = {
  name: PropTypes.string.isRequired,
  email: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
  registered: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired
};

export default LearnMore;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM