在状态和本地存储中反应节省率

时间:2019-03-19 16:33:29

标签: reactjs

我的代码有些麻烦。我制作了一个使用API​​ last fm的应用程序,并且想添加一个评级按钮,但Google的帮助却很少。评分显示在我想要的位置,我可以用控制台登录他,但是它在外部文件上,我不知道如何从我的rate修改app.js状态。这是我的代码:

App.js

import React, { Component } from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import { getArtists } from './services/api';


import {
  TextField,
  Button,
  List
} from '@material-ui/core';

import { ArtistCard } from './components/ArtistCard';
import { SearchResult } from './components/SearchResult';

import './App.css';
import { get } from 'https';

const handleChangeRate = (state) => {
  this.setState({rate: state})
}
const isEmpty = (str) => str.length === 0;
class App extends Component {
  state = {
    searchTerm: '',
    savedArtists: [],
    rate:[]
  }

  componentDidMount() {
    const existing = localStorage.getItem('savedArtists')
    if (existing) {
      this.setState({ savedArtists: JSON.parse(existing) })
    }
  }

  onTextChange = (event) => {
    const value = event.target.value;

    this.setState({ searchTerm: value });
  }

  search = async (terms) => {

    const artists = await getArtists(terms);
    this.setState({ artists: artists })
  }

  onSearchClick = () => {
    this.search(this.state.searchTerm);
  }

  clearSearch = () => {
    this.setState({
      searchTerm: '',
      artists: []
    })
  }

  updateArtists = (newArtists) => {
    this.setState({ savedArtists: newArtists })
    localStorage.setItem('savedArtists', JSON.stringify(newArtists));
  }

  deleteArtist = (artist) => {
    const result = this.state.savedArtists.filter(item => item.name !== artist.name);
    this.updateArtists(result);
  }

  onResultClick = (artist) => {
    this.clearSearch();
    const savedArtists = this.state.savedArtists;
    savedArtists.push(artist);
    this.updateArtists(savedArtists);
  }

   handleChangeRate = (state) => {
    this.setState({rate: state})
  }

  render() {
    const results = this.state.artists || [];
    return (
      <div className="App">
        <header className="App-header">
          <AppBar position="static" color="primary">
            <Toolbar className="search-bar">
              <Typography variant="h6" color="inherit">
                Photos
              </Typography>
              <TextField
                placeholder="Search on Last.fm"
                className="search-input"
                onChange={this.onTextChange}
                value={this.state.searchTerm}
              />
              <Button
                onClick={this.onSearchClick}
                variant="contained"
                color="secondary"
                disabled={isEmpty(this.state.searchTerm)}
              >
                Search
              </Button>
              {!isEmpty(this.state.searchTerm) && (
                <Button
                  onClick={this.clearSearch}
                  variant="contained"
                >
                  Clear
                </Button>)
              }
            </Toolbar>
          </AppBar>
        </header>

        <List className="search-results">
          {
            results.map((artist, index) => {
              return <SearchResult key={index} artist={artist} onResultClick={this.onResultClick} />
            })
          }
        </List>
        <div className="artist-container">
          {
            this.state.savedArtists.map((artist, index) => {
              return <ArtistCard artist={artist} key={index} deleteArtist={this.deleteArtist} onChangeRating={this.handleChangeRate}  /> 
            })
          }
        </div>
      </div>
    );
  }
}

export default App;

artistCard.js

import React from 'react';
import { Card, CardContent, CardActions, Button } from '@material-ui/core'
import ReactStars from 'react-stars'


export const ratingChanged = (newRating) => {
  const { onChangeRating } = this.props;
  onChangeRating(newRating);
}
export const ArtistCard = (props) => {
  const { artist, deleteArtist } = props;
  console.log(artist.cardImage)

  return (
    <Card className="artist-card">
      <div className="image-container">
        <img src={artist.cardImage} alt={artist.name} />
      </div>
      <CardContent>
        <h3>{artist.name}</h3>
        <p>{artist.listeners} listeners.</p>

    <ReactStars
    count = {5}
    onChange={ratingChanged}
    size={27}
    color2 ={'#ffd700'}
    />

      </CardContent>
      <CardActions>
        <Button size="small" color="primary">
          Share
      </Button>
        <Button size="small" color="secondary" onClick={() => deleteArtist(artist)}>
          Delete
      </Button>
      </CardActions>
    </Card>
  )
}

1 个答案:

答案 0 :(得分:0)

您需要传递将State更改为artistCard作为道具的功能

App.js中添加以下功能

const handleChangeRate = (state) => {
  this.setState(rate: state)
}

并将与道具相同的道具传递给指定的ArtistCard

<ArtistCard artist={artist} key={index} deleteArtist={this.deleteArtist} onChangeRating={this.handleChangeRate}  /> 

然后在artistCard.js中将ratingChanged方法更改为

  const ratingChanged = (newRating) => {
  const { onChangeRating } = this.props;
  onChangeRatng(newRating);
}

PS:该答案是基于我对这个问题的理解后得出的,如果不是必需的,请随时发表评论

编辑

const handleChangeRate = (state) => {
  this.setState(rate: state)
}

尝试按如下所示将值prop添加到ReactStart

<ReactStars
  value={this.props.rate}
  count={5}
  onChange={ratingChanged}
  size={24}
  color2={'#ffd700'}
/>

像下面指定的那样,以道具形式通过艺术家卡组件的速率状态

<ArtistCard artist={artist} key={index} deleteArtist= {this.deleteArtist} onChangeRating={this.handleChangeRate} rate={this.state.rate} /> 

编辑 cardComponent.js

import React from 'react';
import ReactStars from 'react-stars'


export const ArtistCard = (props) => {
const { artist, deleteArtist, onChangeRating } = props;
console.log(props.rating)
return (
 <ReactStars
   value={props.rating}
   count = {5}
   onChange={(newRating) => onChangeRating(newRating)}
   size={27}
   color2 ={'#ffd700'}
 />)}

App.js

  handleChangeRate = (state) => {
   this.setState({rate: state})
  }

<ArtistCard artist={'artist'} key={'index'} rating={this.state.rate} deleteArtist={this.deleteArtist} onChangeRating={this.handleChangeRate}  />

最终编辑

您的代码中所做的更改

App.js

将状态对象修改为

state = {
  searchTerm: '',
  savedArtists: [],
  rate: ''
}

Artistcard组件行到

<ArtistCard rate={this.state.rate} artist={artist} key={index} onChangeRating={(val) => {this.setState({ rate: val })}} deleteArtist={this.deleteArtist} />

在ArtistCard.js中

像这样渲染reactstart组件

<ReactStars
   value={props.rate}
   count = {5}
   onChange={(newRating) => onChangeRating(newRating)}
   size={27}
   color2 ={'#ffd700'}
 />