javascript - 搜索功能不适用于前端

标签 javascript reactjs

enter image description here我正在使用 postman 从后端获取数据。但是当我使用前端时,它不起作用。我收到类似的错误 1.TypeError:无法读取 null 的属性“map” 2.未处理的拒绝(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);

最佳答案

据观察,您添加了错误的getproducts URL,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 提供未定义/空的检查,然后渲染组件,因为如果提供错误的 URL 且未定义,则产品可能为空,因为 axios 请求是异步的。因此,通过在现有渲染代码中添加“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>
    )
}

希望能有所帮助..

关于javascript - 搜索功能不适用于前端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52905889/

相关文章:

javascript - 在鼠标悬停 <li> 时显示 Div 但如果鼠标悬停在另一个 li 上则隐藏 div 并显示正确

javascript - Google Analytics 自定义维度不起作用

reactjs - 是否有强制执行 useState() 类型的 eslint 规则?

reactjs - React-Rnd 一个 block 在另一个里面

javascript - react ref.example.value 与 e.target.value

javascript - 如何将firebase返回的数据保存到变量

css - JSX 中内联样式的正确方法

javascript - 如何在 Algolia 中按持续时间搜索

javascript - 如何防止用户删除文本输入中的前三个字符?

javascript - 如何在多维数组内的特定索引处将多个项目插入到数组中?