Отправка в реквизит только при нажатии - PullRequest
0 голосов
/ 04 декабря 2018

Проблема, с которой я сталкиваюсь, заключается в том, что mapDispatchToProps отправляется целиком, и я хочу, чтобы она отправлялась только при нажатии на кнопку удаления.

Это мой класс, его выборка fetchList хорошаявсе работает, как и ожидалось, но когда я добавил кнопку удаления, это, кажется, испортило все это, кажется, вызывает удаление для каждого обновления на странице, есть идеи, почему?

Может ли это быть render(), где я создаю Button, может быть, оно срабатывает без моего нажатия на него?Просто путем создания списка, потому что он запускается для каждого случая, когда каждый itemInList создается через карту.

class List extends Component {
    componentWillMount() {
        this.props.fetchList();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.newItem) {
            this.props.list.unshift(nextProps.newItem);
        }
    }

    onDelete = (id) => {
        this.props.deleteItem(id);
    }

    render() {
        const listItems = this.props.list.map(itemInList => (
            <div key={itemInList.id}> 
                <h3 className="title__font smaller">{itemInList.title} 
                    <Button 
                        btnType="Delete" 
                        onClick={this.onDelete(itemInList.id)}>
                        <i className="fas fa-trash-alt"></i>
                    </Button>
                </h3>
                <p className="body__font">{itemInList.body}</p>
            </div>
        ));
        return (
        <div>
            <h1 className="title__font">List</h1>
            { listItems }
        </div>
        );
    };
};

List.propTypes = {
    fetchList: PropTypes.func.isRequired,
    list: PropTypes.array.isRequired,
    newItem: PropTypes.object
};

const mapStateToProps = state => ({
    list: state.list.items,
    newItem: state.list.item
});

const mapDispatchToProps = dispatch => {
    return {
        fetchList: () => dispatch( actions.fetchList() ),
        deleteItem: (id) => dispatch( actions.deleteItem(id) )
    };
};

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

Это действия для элемента удаления:

export const deleteItem = (id) => dispatch => {
    console.log(id);
    dispatch({
        type: actionTypes.DELETE_ITEM,
        payload: filtered
    })
};

Этот журнал запускается 10 раз в файле действий.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Вы захотите передать объявление функции в onClick, и вам нужно как-то передать id.Мы не хотим объявлять какие-либо функции в методе рендеринга для проблем с производительностью, но нам нужен какой-то способ для передачи id в метод при вызове.Атрибуты данных - отличное решение этой проблемы.

Вот некоторая соответствующая документация.

Во-первых, убедитесь, что контекст this вашего метода привязан кКомпонент выглядит следующим образом:

constructor(props) {
  super(prop)

  this.onDelete = this.onDelete.bind(this)
}

Вышеуказанное необходимо, потому что методы класса фактически определены в их прототипе, а не в отдельных экземплярах.Примечание: если вы используете систему сборки, которая имеет что-то вроде свойств babel-plugin-offer-class-properties, вы можете объявить свой метод следующим образом:

onDelete = (e) => { this.props.deleteItem(e.target.dataset.id) }

Вам нужно будет обновитьВаш onDelete метод выглядит следующим образом:

onDelete = (e) => {
  this.props.deleteItem(e.target.dataset.id);
}

, и вам также необходимо обновить разметку Button в вашем методе рендеринга следующим образом:

<Button
    btnType="Delete"
    data-id={itemInList.id}
    onClick={this.onDelete}
>
    <i className="fas fa-trash-alt"></i>
</Button>

РЕДАКТИРОВАТЬ:

Вот рабочая Кодовая песочница , чтобы продемонстрировать, как все это работает.Мне пришлось внести некоторые изменения в ваш код, такие как исключение не включенного <Button/> компонента.Надеюсь, это поможет вам достичь того, что вам нужно.

0 голосов
/ 04 декабря 2018

Вы немедленно звоните onDelete, поэтому он будет отправлять при рендере.

Попробуйте заменить:

onDelete = (id) => {
  this.props.deleteItem(id);
}

на

onDelete = (id) => () => this.props.deleteItem(id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...