관리 메뉴

프로그래밍 삽질 중

React로 필터 만들기(검색바) - 검색창을 통해 검색하기 본문

과거 프로그래밍 자료들/React

React로 필터 만들기(검색바) - 검색창을 통해 검색하기

평부 2022. 5. 24. 14:35

* '따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기' 강의 참고

* react -> node.js로 이미지 및 정보 저장하기

* mongoDB에 저장하는 것까지 확인

 

 

[1. search를 작동한 js페이지(DataSearch.js 만들기)]

 

[Client]

DataSearch.js

 

import React, { useState } from "react";
import { Input } from "antd";
const { Search } = Input;

function DataSearch() {
  return (
    <div>
      <div>
        <Search
          placeholder="search"
          style={{
            width: 200,
          }}
        />
      </div>
    </div>
  );
}

export default DataSearch;

 

 

[Client]

ShowAllData.js

 

import axios from "axios";
import React, { useEffect, useState } from "react";
import { Card, Row, Col } from "antd";
import ImageSlider from "./Sections/ImageSlider";

import { seasons, price } from "./Sections/Datas";
import DataCheckbox from "./Sections/DataCheckbox";
import DataRadioBox from "./Sections/DataRadioBox";
import DataSearch from "./Sections/DataSearch";

const { Meta } = Card;

function ShowAllData() {
  
  return (
    <div style={{ width: "100%", margin: "0" }}>
      <br />
      <br />
      <br />
      <br />
      <h2 style={{ textAlign: "center" }}>DB에 저장한 거 확인하기</h2>

      <Row>
        {/* checkBox */}
        <Col lg={10} xs={20} style={{ position: "relative", left: "8.5%" }}>
          <DataCheckbox
            list={seasons}
            boxFilters={(filters) => boxFilters(filters, "seasons")}
          />
        </Col>
        {/* radioBox */}
        <Col lg={10} xs={20} style={{ position: "relative", left: "2%" }}>
          {/* RadioBox */}
          <DataRadioBox
            list={price}
            boxFilters={(filters) => boxFilters(filters, "price")}
          />
        </Col>
      </Row>

      {/* search */}
      <div
        style={{
          display: "flex",
          justifyContent: "flex-end",
          margin: "1rem auto",
          width: "65%",
        }}
      >
        <DataSearch /> //추가
      </div>

      {/* card */}
      <div style={{ width: "85%", margin: "1rem auto" }}>
        <Row gutter={[20, 20]}>{renderCard}</Row>
      </div>

      {LimitImage >= End && (
        <div style={{ display: "flex", justifyContent: "center" }}>
          <button style={{}} onClick={showMoreData}>
            더 보기
          </button>
        </div>
      )}
    </div>
  );
}

export default ShowAllData;

 

[1. search를 작동하게 하는 기능 만들기]

 

[Client]

 

DataSearch.js

 

import React, { useState } from "react";
import { Input } from "antd";
const { Search } = Input;

function DataSearch(props) {
  const [SearchItem, setSearchItem] = useState("");

  const searchHandler = (event) => {
    setSearchItem(event.currentTarget.value);
    props.refreshFunction(event.currentTarget.value);
  };

  return (
    <div>
      <div>
        <Search
          placeholder="search"
          style={{
            width: 200,
          }}
          value={SearchItem}
          onChange={searchHandler}
        />
      </div>
    </div>
  );
}

export default DataSearch;

 

 

[Client]

ShowAllData.js

 

import axios from "axios";
import React, { useEffect, useState } from "react";
import { Card, Row, Col } from "antd";
import ImageSlider from "./Sections/ImageSlider";

import { seasons, price } from "./Sections/Datas";
import DataCheckbox from "./Sections/DataCheckbox";
import DataRadioBox from "./Sections/DataRadioBox";
import DataSearch from "./Sections/DataSearch";

const { Meta } = Card;

function ShowAllData() {
  const [SearchItem, setSearchItem] = useState("");

  useEffect(() => {
    let body = {
      start: Start,
      end: End,
    };

    commonAxios(body);
  }, []);

  //더 보기에 두 번 들어가기 때문에 따로 분리
  const commonAxios = (body) => {
    //post에 info값 넣을 것
    axios.post("/api/data/list", body).then((response) => {
      if (response.data.success) {
        // console.log(response.data);

        if (body.showMore) {
          setDatas([...Datas, ...response.data.dataInfo]);
        } else {
          setDatas(response.data.dataInfo);
        }
        setLimitImage(response.data.limitImage);
      } else {
        alert("상품을 가져오는데 실패했습니다.");
      }
    });
  };

 
  const updateSearchItem = (newSearchItem) => {
    let body = {
      start: 0,
      end: End,
      filters: Filters,
      searchItem: newSearchItem,
    };

    setStart(0);
    setSearchItem(newSearchItem);
    commonAxios(body);
  };

  return (
    <div style={{ width: "100%", margin: "0" }}>
      <br />
      <br />
      <br />
      <br />
      <h2 style={{ textAlign: "center" }}>DB에 저장한 거 확인하기</h2>

      <Row>
        {/* checkBox */}
        <Col lg={10} xs={20} style={{ position: "relative", left: "8.5%" }}>
          <DataCheckbox
            list={seasons}
            boxFilters={(filters) => boxFilters(filters, "seasons")}
          />
        </Col>
        {/* radioBox */}
        <Col lg={10} xs={20} style={{ position: "relative", left: "2%" }}>
          {/* RadioBox */}
          <DataRadioBox
            list={price}
            boxFilters={(filters) => boxFilters(filters, "price")}
          />
        </Col>
      </Row>

      {/* search */}
      <div
        style={{
          display: "flex",
          justifyContent: "flex-end",
          margin: "1rem auto",
          width: "65%",
        }}
      >
        <DataSearch refreshFunction={updateSearchItem} /> //추가
      </div>

      {/* card */}
      <div style={{ width: "85%", margin: "1rem auto" }}>
        <Row gutter={[20, 20]}>{renderCard}</Row>
      </div>

      {LimitImage >= End && (
        <div style={{ display: "flex", justifyContent: "center" }}>
          <button style={{}} onClick={showMoreData}>
            더 보기
          </button>
        </div>
      )}
    </div>
  );
}

export default ShowAllData;

 

 

[Server]

 

Data.js(스키마 포함된 값)

 

const mongoose = require("mongoose");

const dataSchema = mongoose.Schema(
  {
    title: {
      type: String,
    },
    description: {
      type: String,
      maxlength: 50,
    },
    images: {
      type: Array,
      default: [],
    },
    seasons: {
      type: Number,
      default: 1,
    },
    price: {
      type: Number,
      default: 0,
    },

    //시간 자동 업데이트
  },
  { timestamps: true }
);

dataSchema.index(
  {
    title: "text",
    description: "text",
  },
  {
    weight: {
      title: 5,
      description: 1,
    },
  }
);

const Data = mongoose.model("Data", dataSchema);

module.exports = { Data };

 

 

[Server]

data.js(routes)

 

router.post("/list", (req, res) => {
 
  let item = req.body.searchItem;

  if (item) { //검색기능이 포함된 값
    Data.find(findData)
      .find({ $text: { $search: item } })
      .populate("title")
      .skip(start)
      .limit(end)
      .exec((err, dataInfo) => {
        if (err) return res.status(400).json({ success: false, err });
        return res
          .status(200)
          .json({ success: true, dataInfo, limitImage: dataInfo.length });
      });
  } else { //검색기능이 포함되지 않은 값
    Data.find(findData)
      .populate("title")
      .skip(start)
      .limit(end)
      .exec((err, dataInfo) => {
        if (err) return res.status(400).json({ success: false, err });
        return res
          .status(200)
          .json({ success: true, dataInfo, limitImage: dataInfo.length });
      });
  }
});

 

* $text : MongoDB에 있는 검색기능

* 출처 : (https://www.mongodb.com/docs/manual/reference/operator/query/text/#mongodb-query-op.-text)

 

 

 

* 결과