反应-面试练习

时间:2019-02-18 15:19:49

标签: javascript reactjs

在一次采访中,我获得了以下包含2个组件的React练习,但我没有设法对其进行编译... 问题如下:

更新Counter组件以将onIncrement回调作为道具,并确保它们独立更新Counter的值。每个回调应采用一个单个整数值作为参数,该值是将计数器现有值增加的量。

在代码中注释,但是我的问题是如何实现“ onIncrement”功能。

const { Component } = React;
const { render } = ReactDOM;

// state data for 3 counters
const data = [
  { id: 1, value: 1 },
  { id: 2, value: 2 },
  { id: 3, value: 3 }
];

// Counter Component
class Counter extends Component {
  render() {
    const { value } = this.props;
    return (
      <div className="counter">
        <b>{value}</b>
        <div className="counter-controls">
          <button className="button is-danger is-small">-</button>
          //I call the function passed     
          <button className="button is-success is-small" onClick={()=>{onIncrement(this.props.value)}}>+</button>
        </div>
      </div>
    );
  }
}

class App extends Component {
  constructor(props, context) {
    super(props, context);
  }
  
   onIncrement=(value)=>{
   //I tried several things here but I did not manage to make it work. I guess that I need also the id of the object...
   }

  render() {
    return (
      <div>
       
        {data.map(counter => ( 
          <Counter 
            key={counter.id} 
            value={counter.value} 
             //I pass the callback function to the component
            onIncrement={this.onIncrement} 

            />
        ))}
      </div>
    );
  }
}


render(
  <App/>
, document.querySelector('#root'))

2 个答案:

答案 0 :(得分:0)

基本上,您将希望使用id作为确定需要更新哪个value的方式。如何进行设置,您将无法知道需要更新哪个value(因为您不知道单击了哪个id),也无法知道value保存。

注意:以下示例从id提取event.target.id,从value提取event.target.value,然后在{{1 }} 打回来。与将值传递给handleChange然后将其和另一个值传递给另一个callback(这是更多的工作,更多的代码,但功能相同)相比,这是一种更常见,更优雅的解决方案。


最佳解决方案https://codesandbox.io/s/rjmx8vw99p

components / UpdateQuantity.js

callback

另一种解决方案https://codesandbox.io/s/yq961275rv(不建议使用,因为它需要额外的组件和额外的回调-但是import React, { Component, Fragment } from "react"; export default class App extends Component { state = { items: [ { id: "Apples", quantity: 0 }, { id: "Strawberries", quantity: 0 }, { id: "Grapes", quantity: 0 }, { id: "Apricots", quantity: 0 } ] }; handleChange = ({ target: { id, value } }) => { this.setState(prevState => ({ items: prevState.items.map(item => { const nextVal = item.quantity + ~~value; // ~~ === parseInt(val, 10) -- required because the "value" is turned into a string when placed on a DOM element return id === item.id ? { id, quantity: nextVal > 0 ? nextVal : 0 } : { ...item }; }) })); }; render = () => ( <div className="container"> <h1>Updating Values Inside Array</h1> {this.state.items.map(({ id, quantity }) => ( <div key={id} className="container"> <div> {id} ({quantity}) </div> <button id={id} value={1} style={{ marginRight: 10 }} className="uk-button uk-button-primary" onClick={this.handleChange} > + </button> <button id={id} value={-1} style={{ marginRight: 10 }} className="uk-button uk-button-danger" onClick={this.handleChange} > - </button> </div> ))} </div> ); } 方法中不需要绑定,也没有render回调中的匿名函数() => {}

components / UpdateQuantity.js

onClick

components / button.js

import React, { Component, Fragment } from "react";
import Button from "./button";

export default class App extends Component {
  state = {
    items: [
      { id: "Apples", quantity: 0 },
      { id: "Strawberries", quantity: 0 },
      { id: "Grapes", quantity: 0 },
      { id: "Apricots", quantity: 0 }
    ]
  };

  handleChange = (id, val) => {
    this.setState(prevState => ({
      items: prevState.items.map(item => {
        const nextVal = item.quantity + val;

        return id === item.id
          ? { id, quantity: nextVal > 0 ? nextVal : 0 }
          : { ...item };
      })
    }));
  };

  render = () => (
    <div className="container">
      <h1>Updating Values Inside Array</h1>
      {this.state.items.map(props => (
        <div key={props.id} className="container">
          <div>
            {props.id} ({props.quantity})
          </div>
          <Button
            {...props}
            className="uk-button uk-button-primary"
            handleChange={this.handleChange}
            value={1}
          >
            +
          </Button>
          <Button
            {...props}
            disabled={props.quantity === 0}
            className="uk-button uk-button-danger"
            handleChange={this.handleChange}
            value={-1}
          >
            -
          </Button>
        </div>
      ))}
    </div>
  );
}

答案 1 :(得分:0)

我知道答案已经被接受,但实际上并不能完全满足要求

  

每个回调都应使用一个整数值作为参数,该值是将计数器现有值增加的量。

接受的答案将事件对象作为参数,而不是指定的要求。严格满足预期要求的唯一方法是绑定唯一

  

“ ... onIncrement回调作为道具...”

每个计数器

。这种方法具有缺点和性能暗示as discussed in this article

工作示例,位于 https://codesandbox.io/s/j2vxj620z9