React-Redux App:处理无状态组件中的事件

时间:2018-10-13 15:46:47

标签: javascript reactjs redux react-redux

我之前用不同的形式问过同样的问题,但是还没有找到合适的解决方案。我想避免在删除数据并使用无状态组件定义数据时刷新页面。有我的示例代码:

BookListElement.js

import React from 'react';
import { connect } from 'react-redux';
import BookList from '../components/bookList';
import { deleteBook } from '../store/actions/projectActions';

const BookListElement = ({books, deleteBook}) => {
  if(!books.length) {
    return (
      <div>
        No Books
      </div>
    )
  }
  return (
    <div>
      {Array.isArray(books) ? books.map(book => {
        return (
          <BookList book={book} deleteBook={deleteBook} key={book._id} />
        );
      }): <h1>something wrong.</h1>}
    </div>
  );
};

const mapStateToProps = state => {
  return {
    books: state.books
  };
};

const mapDispatchToProps = dispatch => {
  return {
    deleteBook: _id => {
      dispatch(deleteBook(_id));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(BookListElement);

bookList.js

import React from 'react';

const styles = {
  borderBottom: '2px solid #eee',
  background: '#fafafa',
  margin: '.75rem auto',
  padding: '.6rem 1rem',
  maxWidth: '500px',
  borderRadius: '7px'
};

const BookList = ({ book: { author, publication, publisher, _id }, deleteBook }) => {
  const handleClick = (e) => {
    e.preventDefault();
    deleteBook(_id);
  }
  return (
        <form>
      <div className="collection-item" style={styles} key={_id}>
        <h2>{author}</h2>
        <p>{publication}</p>
        <p>{publisher}</p>
        <button className="btn waves-effect waves-light" onClick={handleClick}>
          <i className="large material-icons">delete_forever</i>
        </button>
      </div>
    </form>
  );
};

export default BookList;

action.js

export const deleteBookSuccess = _id => {
  return {
    type: DELETE_BOOK,
    payload: {
      _id
    }
  }
};

export const deleteBook = _id => {
  return (dispatch) => {
    return axios.delete(`${apiUrl}/${_id}`)
      .then(response => {
        dispatch(deleteBookSuccess(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

reducer.js

const projectReducer = (state = [], action) => {
    case DELETE_BOOK:
          let afterDelete = state.filter(book => {
            return book._id !== action.payload._id
          });
          return afterDelete;
}

如您所见,我在handleClick的{​​{1}}中定义了onClick,并且删除数据后仍需要刷新页面。大三时我应该如何适当地克服这个问题?

3 个答案:

答案 0 :(得分:0)

我认为问题是您尚未为<button>设置类型。对于大多数浏览器,如果未指定类型,则将其设置为<button type='submit'>

将其设置为BookList中的<button type='button'>,以避免提交表单。

答案 1 :(得分:0)

问题在于,本机<form>提交事件仍在发生,导致单击按钮时页面刷新。通过将onSubmit元素上的<form>事件作为目标,尝试以下操作来防止本机表单。这将使您可以preventDefault()进行提交事件。

// ...

const BookList = ({ book: { author, publication, publisher, _id }, deleteBook }) => {
  const handleSubmit = (e) => {
    e.preventDefault();
    deleteBook(_id);
  }
  return (
     <form onSubmit={handleSubmit}>
      <div className="collection-item" style={styles} key={_id}>
        <h2>{author}</h2>
        <p>{publication}</p>
        <p>{publisher}</p>
        <button type="submit" className="btn waves-effect waves-light">
          <i className="large material-icons">delete_forever</i>
        </button>
      </div>
    </form>
  );
};

export default BookList;

注意:在onSubmit元素上使用<form>时,您需要从按钮中删除onClick。使用<button type="submit",单击按钮将导致发生表单提交事件,该事件将在handleSubmit中处理。

更新

鉴于您使用的是React Router,请确保将withRouter用于Redux Integration。尝试用withRouter高阶组件包装BookListElement。假设您正在使用react-router-dom

import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import BookList from '../components/bookList';
import { deleteBook } from '../store/actions/projectActions';

// ...

export default withRouter(connect(
  mapStateToProps,
  mapDispatchToProps
)(BookListElement));

希望有帮助!

答案 2 :(得分:0)

您的React代码按预期工作:https://glitch.com/edit/#!/so-52794886

如果在删除其中一本书后图书列表没有更新,则可能是从服务器返回的_id是字符串类型,而redux存储中的_ids是数字类型,因此过滤谓词永远不会匹配,并且永远不会从列表中删除该项目。