javascript - 在 React 中禁用 onClick 按钮,但仅对 Index 中的一个元素禁用

标签 javascript reactjs

在我的应用程序中,我有一个用于切换类的添加按钮,该按钮位于卡片元素中,该元素填充来自其余 api 的数据。

当我单击按钮时,它会切换所有卡片上按钮的类,而它应该只切换我单击的卡片上的类。我知道这一定与索引有关,但下面的代码到目前为止还不起作用:

组件.js

import React, { Component } from 'react';
import './news.css';
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";

const responsive = {
    superLargeDesktop: {
        breakpoint: { max: 4000, min: 3000 },
        items: 5,
    },
    desktop: {
        breakpoint: { max: 3000, min: 1024 },
        items: 3,
    },
    tablet: {
        breakpoint: { max: 1024, min: 464 },
        items: 2,
    },
    mobile: {
        breakpoint: { max: 464, min: 0 },
        items: 1,
    },
};

class News extends Component {

    state = {
        loading: false,
        data: [],
        headline: [],
        saved: [],
        condition: false
    }


    saved = data => {
        this.setState(
            (prevState) => ({ saved: [...prevState.saved, data], condition: !this.state.condition}),
            () => {
                console.log('Saved articles = ', this.state.saved);
                alert('Article saved');
                localStorage.setItem('saved', JSON.stringify(this.state.saved));
                localStorage.getItem('saved');
            });
    }

    onError() {
        this.setState({
            imageUrl: "../assets/img-error.jpg"
        })
    }

    constructor(props) {
        super(props)
        this.saved = this.saved.bind(this)
    }

    componentDidMount() {
        this.setState({ loading: true, saved: localStorage.getItem('saved') ? JSON.parse(localStorage.getItem('saved')) : [] })
        console.log('app mounted');
        fetch('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=?')
            .then(data => data.json())
            .then(data => this.setState({ data: data.articles, loading: false }, () => console.log(data.articles)))
    }

    render() {
        return (
            <div className="news">
                {this.state.loading
                    ? "loading..."
                    : <div className="container">
                        <h3 className="text-left">Featured News</h3>
                        <Carousel
                            additionalTransfrom={0}
                            showDots={true}
                            arrows={false}
                            autoPlay={true}
                            autoPlaySpeed={3000}
                            centerMode={false}
                            className="carousel"
                            containerClass="container-with-dots"
                            dotListClass=""
                            draggable
                            focusOnSelect={false}
                            infinite
                            keyBoardControl
                            minimumTouchDrag={80}
                            renderButtonGroupOutside={true}
                            renderDotsOutside={true}
                            responsive={responsive}>
                            {this.state.data.map((post, indx) => {
                                return (
                                    <div className="card card-news text-left mt-3" key={indx}>
                                        <img className="media-img card-img-top card-img" src={post.urlToImage} alt="Alt text"></img>
                                        <div className="card-body">
                                            <h4 className="card-title block-with-text-2">{post.title}</h4>
                                            <button className={this.state.condition ? "btn-danger btn mt-2 mb-4" : "btn-primary btn mt-2 mb-4"}
                                                onClick={() => this.saved(post)}>{this.state.condition ? "Remove Article" : "Add Article"}</button>
                                            <p className="card-text block-with-text">{post.description}</p>
                                            <a className="button-bottom" href={post.url} target="_blank" rel="noopener noreferrer">Read More</a>
                                        </div>
                                    </div>
                                )
                            })}
                        </Carousel>
                    </div>
                }
            </div>
        )
    }
}
export default News;

任何想法

最佳答案

我想说,只需更新 data 数组中的项目即可。例如,如果单击了项目,我们要添加 isSaved = true 键。

class News extends Component {

    state = {
        loading: false,
        data: [],
        headline: [],
        saved: [],
        condition: false
    }


    saved = port => {
        const { data } = this.state;
        const index = data.findIndex(obj => obj.id === post.id);
        data[index].isSaved = !data[index].isSaved;
        this.setState({ data: [...data] });
    }

    onError = () => {
        this.setState({
            imageUrl: "../assets/img-error.jpg"
        })
    }

    componentDidMount() {
        this.setState({ loading: true, saved: localStorage.getItem('saved') ? JSON.parse(localStorage.getItem('saved')) : [] })
        console.log('app mounted');
        fetch('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=?')
            .then(data => data.json())
            .then(data => this.setState({ data: data.articles, loading: false }, () => console.log(data.articles)))
    }

    render() {
        return (
            <div className="news">
                {this.state.loading
                    ? "loading..."
                    : <div className="container">
                        <h3 className="text-left">Featured News</h3>
                        <Carousel
                            additionalTransfrom={0}
                            showDots={true}
                            arrows={false}
                            autoPlay={true}
                            autoPlaySpeed={3000}
                            centerMode={false}
                            className="carousel"
                            containerClass="container-with-dots"
                            dotListClass=""
                            draggable
                            focusOnSelect={false}
                            infinite
                            keyBoardControl
                            minimumTouchDrag={80}
                            renderButtonGroupOutside={true}
                            renderDotsOutside={true}
                            responsive={responsive}>
                            {this.state.data.map((post, indx) => {
                               // ----------------------------------------------------
                               console.log('Do something with post.isSaved value')
                               // -----------------------------------------------------
                                return (
                                    <div className="card card-news text-left mt-3" key={indx}>
                                        <img className="media-img card-img-top card-img" src={post.urlToImage} alt="Alt text"></img>
                                        <div className="card-body">
                                            <h4 className="card-title block-with-text-2">{post.title}</h4>
                                            <button className={this.state.condition ? "btn-danger btn mt-2 mb-4" : "btn-primary btn mt-2 mb-4"}
                                                onClick={() => this.saved(post)}>{this.state.condition ? "Remove Article" : "Add Article"}</button>
                                            <p className="card-text block-with-text">{post.description}</p>
                                            <a className="button-bottom" href={post.url} target="_blank" rel="noopener noreferrer">Read More</a>
                                        </div>
                                    </div>
                                )
                            })}
                        </Carousel>
                    </div>
                }
            </div>
        )
    }
}
export default News;

关于javascript - 在 React 中禁用 onClick 按钮,但仅对 Index 中的一个元素禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59940598/

相关文章:

javascript - 为什么 $(window).animate scrollTop 不起作用?

javascript - 在 d3.layout.tree() 中自定义单个坐标

reactjs - 使用 useEffect 监听子组件可以吗?

javascript - 如何测试返回函数值

javascript - 如何使用 HOC 编写适当的 Jest 测试?

javascript - undefined 解构中的默认值

javascript - 动态箭头颜色

javascript - 浏览器之间使用 "let"关键字的不同变量作用域

javascript - react native : require() with Dynamic String?

reactjs - 类型属性依赖于另一个属性的返回类型