Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
126 views
in Technique[技术] by (71.8m points)

javascript - Search field kicks me out on input field after 1 letter

this is in React. I have a search input field, however after typing one letter it keeps me out of the input field and renders the page again. The search field does work, it just kicks me out. I've tried adding a

onChange={(e) => setSearchField(e.target.value), function(e) {
  e.preventDefault();
}}

to the input field but it doesn't work. Here's my whole file:

import React, { useState, useEffect } from "react";
import { Container, Row, Col, Input } from "reactstrap";
import MeetingTable from "./MeetingTable";
import MeetingCreate from "./MeetingCreate";
import MeetingEdit from "./MeetingEdit";
import APIURL from "../helpers/environment";
import styled from "styled-components";
import "./MeetingMain.css";

const MeetingMain = (props) => {
  const Div = styled.div`
    background-color: #363136;
    opacity: 0.8;
    border-radius: 5px;
    padding-top: 10px;
    padding-left: 10px;
  `;

  const [meetings, setMeetings] = useState([]);
  const [updateActive, setUpdateActive] = useState(false);
  const [meetingToUpdate, setMeetingToUpdate] = useState({});
  const [searchField, setSearchField] = useState("");

  const tableStyle = {
    display: "flex",
    flexDirection: "column",
    justifyContent: "center",
    alignItems: "center",
    maxWidth: "1175px",
  };

  const fetchMeetings = () => {
    fetch(`${APIURL}/meeting`, {
      method: "GET",
      headers: new Headers({
        "Content-Type": "application/json",
        Authorization: props.token,
      }),
    })
      .then((res) => res.json())
      .then((logData) => {
        setMeetings(logData.meetings);
        console.log(logData.meetings);
      });
  };

  const editUpdateMeeting = (meeting) => {
    setMeetingToUpdate(meeting);
    console.log(meeting);
  };

  const updateOn = () => {
    setUpdateActive(true);
  };

  const updateOff = () => {
    setUpdateActive(false);
  };

  useEffect(() => {
    fetchMeetings();
  }, []);

  const filteredMeetings = meetings.filter((meeting) =>
    meeting.day.toLowerCase().includes(searchField.toLowerCase())
  );

  return (
    <Div>
      <Container style={tableStyle}>
        <Row>
          <Col md="12">
            <MeetingCreate fetchMeetings={fetchMeetings} token={props.token} />
          </Col>
          <Col md="12">
            <Input
              className="search-field"
              type="search"
              placeholder="Search Meetings"
              onChange={(e) => setSearchField(e.target.value)}
              value={searchField}
            />
            <MeetingTable
              meetings={filteredMeetings}
              editUpdateMeeting={editUpdateMeeting}
              updateOn={updateOn}
              fetchMeetings={fetchMeetings}
              token={props.token}
            />
          </Col>
          {updateActive ? (
            <MeetingEdit
              meetingToUpdate={meetingToUpdate}
              updateOff={updateOff}
              token={props.token}
              fetchMeetings={fetchMeetings}
            />
          ) : (
            <></>
          )}
        </Row>
      </Container>
    </Div>
  );
};

export default MeetingMain;

So I'm a bit at a loss on what's causing this. Any help would be appreciated.

question from:https://stackoverflow.com/questions/65896036/search-field-kicks-me-out-on-input-field-after-1-letter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Issue

You're defining a styled component inside your functional component, this means it's a new component each render cycle. In other words, it is a new component and mounted & rendered versus just being rerendered when state updates from the onChange handler.

Define Styled Components outside of the render method

It is important to define your styled components outside of the render method, otherwise it will be recreated on every single render pass. Defining a styled component within the render method will thwart caching and drastically slow down rendering speed, and should be avoided.

Recall: The entire body of a functional component IS the render "method".

Solution

Declare the Div component outside MeetingMain so it is a stable component reference.

const Div = styled.div`
  background-color: #363136;
  opacity: 0.8;
  border-radius: 5px;
  padding-top: 10px;
  padding-left: 10px;
`;

const MeetingMain = (props) => {
  const [meetings, setMeetings] = useState([]);
  const [updateActive, setUpdateActive] = useState(false);
  const [meetingToUpdate, setMeetingToUpdate] = useState({});
  const [searchField, setSearchField] = useState("");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...