0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[MERN] 検索機能

Last updated at Posted at 2020-12-02

1. SearhBox作成

components/layout/SearchBox.js
import React, { useState } from 'react';
import { Form, Button } from 'react-bootstrap';

const SearchBox = ({ history }) => {
  const [keyword, setKeyword] = useState('');

  const submitHandler = (e) => {
    e.preventDefault();
    if (keyword.trim()) {
      history.push(`/search/${keyword}`);
    } else {
      history.push('/');
    }
  };

  return (
    <Form onSubmit={submitHandler} inline>
      <Form.Control
        type="text"
        name="q"
        onChange={(e) => setKeyword(e.target.value)}
        placeholder="Search Products..."
        className="mr-sm-2 ml-sm-5"
      ></Form.Control>
      <Button type="submit" variant="outline-success" className="p-2">
        Search
      </Button>
    </Form>
  );
};

export default SearchBox;

2. search/:keywordのRoute設置

components/routing/Routes.js
//...
const Routes = () => {
//...
        <Route exact path="/profile/:id" component={Profile} />
+       <Route exact path="/search/:keyword" component={Posts} />
        <Route exact path="/posts" component={Posts} />
        <Route exact path="/posts/:id" component={Post} />
//...

3. Navbarに検索フォーム設置

components/layout/Navbar.js
//...
import PropTypes from 'prop-types';
+ import SearchBox from './SearchBox';
import { logout } from '../../actions/auth';

const Navbar = ({ auth: { isAuthenticated, loading }, logout }) => {
//...
  return (
    <nav className="navbar bg-dark">
      <h1>
        <Link to="/posts">
          <i className="fas fa-code" /> Refnote
        </Link>
      </h1>

+      <Route render={({ history }) => <SearchBox history={history} />} />

      {!loading && (
        <Fragment>{isAuthenticated ? authLinks : guestLinks}</Fragment>
      )}
    </nav>
  );
};
//...

4. Posts一覧にkeyword Params設置

components/posts/Posts.js
//...
import { getPosts } from '../../actions/post';

+ const Posts = ({ getPosts, post: { posts, loading }, match, auth }) => {
+  const keyword = match.params.keyword;

  useEffect(() => {
+    getPosts(keyword);
+  }, [getPosts, keyword]);

  return loading ? (
//...
      <div className="Posts">
        {posts.map((post) => (
          <PostItem key={post._id} post={post} />
        ))}
      </div>
    </Fragment>
  );
};
//...

5. getPostsアクションにKeyword Propsを設置

actions/post.js
//...
// Get posts
+ export const getPosts = (keyword = '') => async (dispatch) => {
  try {
+    const res = await axios.get(`/api/posts?keyword=${keyword}`);
    dispatch({
      type: GET_POSTS,
      payload: res.data,
    });
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status },
    });
  }
};
//...

6. postsAPIを編集

routes/api/posts.js
//...
// @route  GET api/posts
// @desc   Get all posts
// @access Public
router.get('/', async (req, res) => {
+ const keyword = req.query.keyword
+   ? {
+       text: {
+         $regex: req.query.keyword,
+         $options: 'i',
+       },
+     }
+   : {};

  try {
+   const posts = await Post.find({ ...keyword }).sort({ date: -1 });
    res.json(posts);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});
//...
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?