搜索功能不适用于前端

时间:2018-10-20 12:56:06

标签: javascript reactjs

enter image description here我正在使用邮递员从后端获取数据。但是当我使用前端相同时,它不起作用。我收到类似的错误 1.TypeError:无法读取null的属性“ map” 2.Unhandled Rejection(TypeError):无法读取null的属性“ map”。

我认为,我收到此错误是因为搜索时卡无法渲染。后端数据以数组的形式出现。

enter image description here

const styles = theme => ({
  appBar: {
    position: 'relative',
  },
  icon: {
    marginRight: theme.spacing.unit * 2,
  },
  layout: {
    width: 'auto',
    marginLeft: theme.spacing.unit * 3,
    marginRight: theme.spacing.unit * 3,
    [theme.breakpoints.up(1100 + theme.spacing.unit * 3 * 2)]: {
      width: 1100,
      marginLeft: 'auto',
      marginRight: 'auto',
    },
  },
  cardGrid: {
    padding: `${theme.spacing.unit * 8}px 0`,
  },
  card: {
    height: '100%',
    display: 'flex',
    flexDirection: 'column',
  },
  cardContent: {
    flexGrow: 1,
  },
});

class Products extends Component {


  constructor(props) {
    super(props);

    this.state = {
      products: [],
      searchString: ''
    };
    this.onSearchInputChange = this.onSearchInputChange.bind(this);
    this.getProducts = this.getProducts.bind(this);
  }

  componentDidMount() {
    this.getProducts();
  }



  // delete = id => {
  //   axios.post('http://localhost:9022/products/delete/' + id)
  //     .then(res => {
  //       let updatedProducts = [...this.state.products].filter(i => i.id !== id);
  //       this.setState({ products: updatedProducts });
  //     });
  // }

  delete = id => {
    axios.post('http://localhost:9022/products/delete/' + id)
      .then(res => {

        this.setState((prevState, prevProps) => {
          let updatedProducts = [...prevState.products].filter(i => i.id !== id);
          return ({
            products: updatedProducts
          });
        });
      });
  }

  getProducts() {
    axios.get('http://localhost:9022/products/getAll')
      .then(res => {
        this.setState({ products: res.data }, () => {
          console.log(this.state.products);
        });
      });
  }

  onSearchInputChange = (event) => {
    let newSearchString = '';
    if (event.target.value) {
      newSearchString = event.target.value;
    }
    axios.get('http://localhost:9022/products/getproducts' + newSearchString)
      .then(res => {
        this.setState({ products: res.data });
        console.log(this.state.products);
      });
    this.getProducts();
  }

  // onSearchInputChange(event) {
  //   let newSearchString = '';
  //   if (event.target.value) {
  //     newSearchString = event.target.value;
  //   }

  //   // call getProducts once React has finished updating the state using the callback (second argument)
  //   this.setState({ searchString: newSearchString }, () => {
  //     this.getProducts();
  //   });
  // }

  render() {
    const { classes } = this.props;
    return (
      <React.Fragment>
        <TextField style={{ padding: 24 }}
          id="searchInput"
          placeholder="Search for products"
          margin="normal"
          onChange={this.onSearchInputChange} />
        <CssBaseline />
        <main>
          <div className={classNames(classes.layout, classes.cardGrid)}>
            <Grid container spacing={40}>
              {this.state.products.map(currentProduct => (
                <Grid item key={currentProduct.id} sm={6} md={4} lg={3}>
                  <Card className={classes.card}>

                    <CardContent className={classes.cardContent}>
                      <Typography gutterBottom variant="h5" component="h2">
                        {currentProduct.title}
                      </Typography>
                      <Typography>
                        {currentProduct.price}
                      </Typography>
                    </CardContent>
                    <CardActions>

                      <Button size="small" color="primary" component={Link} to={"/products/" + currentProduct.id}>
                        Edit
                    </Button>
                      <Button size="small" color="primary" onClick={() => this.delete(currentProduct.id)}>
                        Delete
                    </Button>
                    </CardActions>
                  </Card>
                </Grid>
              ))}
            </Grid>
          </div>
        </main>
      </React.Fragment>
    )
  }
}

Products.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(Products);

2 个答案:

答案 0 :(得分:2)

已观察到,您添加了错误的URL getproducts,URL中没有斜杠。请在下面找到详细信息:

如果搜索字符串为r,则您正在使用以下getproducts URL:http://localhost:9022/products/getproductsr

这是错误的,应该为http://localhost:9022/products/getproducts/r

因此,您必须按以下方式更改产品检索代码:

axios.get('http://localhost:9022/products/getproducts/' + newSearchString)
.then(res => {
    this.setState({ products: res.data });
    console.log(this.state.products);
});

最好为this.state.products提供一个undefined / null的检查,然后渲染组件,因为如果一个提供错误的URL并且axios请求是异步的,那么product可能为null。因此,通过在现有渲染代码中添加'this.state.products &&'可以避免此类问题。我已经更新了您的渲染功能,请在下面找到它:

render() {
    const { classes } = this.props;
    return (
      <React.Fragment>
        <TextField style={{ padding: 24 }}
          id="searchInput"
          placeholder="Search for products"
          margin="normal"
          onChange={this.onSearchInputChange} />
        <CssBaseline />
        <main>
          <div className={classNames(classes.layout, classes.cardGrid)}>
            <Grid container spacing={40}>
              {this.state.products && this.state.products.map(currentProduct => (
                <Grid item key={currentProduct.id} sm={6} md={4} lg={3}>
                  <Card className={classes.card}>

                    <CardContent className={classes.cardContent}>
                      <Typography gutterBottom variant="h5" component="h2">
                        {currentProduct.title}
                      </Typography>
                      <Typography>
                        {currentProduct.price}
                      </Typography>
                    </CardContent>
                    <CardActions>

                      <Button size="small" color="primary" component={Link} to={"/products/" + currentProduct.id}>
                        Edit
                    </Button>
                      <Button size="small" color="primary" onClick={() => this.delete(currentProduct.id)}>
                        Delete
                    </Button>
                    </CardActions>
                  </Card>
                </Grid>
              ))}
            </Grid>
          </div>
        </main>
      </React.Fragment>
    )
}

希望这会有所帮助。

答案 1 :(得分:1)

您可以尝试以下方法:

您只是错过了api端点中的斜杠,如下所示:请使用此

axios.get('http://localhost:9022/products/getproducts/' + newSearchString)

而不是:

axios.get('http://localhost:9022/products/getproducts' + newSearchString)