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

时间:2019-04-13 21:06:21

标签: javascript reactjs

我正在将React用于搜索应用程序的前端。

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

上方的搜索栏应保留在原位,如果用户搜索新信息,则应删除了解的更多信息,并应显示新的结果列表。

我无法显示更多信息。

我遇到的最大问题是必须将表单与onSubmit函数一起使用,并且一旦调用onSubmit函数,我的结果将保留几秒钟,然后所有内容都会消失。

以下显示了我文件中与该问题有关的部分


def render(self):
        # score
        d = self.screen.blit(self.bg, SCORE_POS, pygame.Rect(SCORE_POS, (50, 100)))
        f = pygame.font.Font(None, 12)
        scoreimage = f.render(SCORE_PREFIX + str(self.currentscore), True, SCORE_COLOR)
        d2 = self.screen.blit(scoreimage, SCORE_POS)

        # drawing
        dirty = self.all.draw(self.screen)
        dirty.append(d)
        dirty.append(d2)

        # updating screen
        pygame.display.update(dirty)

        # waiting
        self.clock.tick(FPS)

2 个答案:

答案 0 :(得分:0)

您应该像这样进行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 })
}

答案 1 :(得分:0)

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

请注意,此示例使用了许多ES6语法。请阅读以下内容以了解其工作原理:fat arrow functionsES6 destructionspread operatorternary operatorclass propertiesa controlled react form utilizing event handlers and state,{{ 3}}和array filtering

要花很多钱,所以如果您有任何疑问,请随时提问。

工作示例

type checking with 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;

组件/ SearchBar

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;

组件/了解更多

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;