#9 百分比换算器


  • 0
    administrators

    做一个百分比换算器,需要你完成三个组件:

    <Input />:封装了原生的<input />,可以输入任意数字

    <PercentageShower />实时 显示 <Input /> 中的数字内容,但是需要把它转换成百分比,例如 <Input /> 输入的是 0.1,那么就要显示 10.00%,保留两位小数。

    <PercentageApp />:组合上述两个组件。


  • 0

    @胡子大哈
    Input

    <input type='number' ... value={this.props.num}/>
    
    PercentageApp
    <div>
            <Input onSetNum={this.handleSetNum.bind(this)} num={this.state.num}/>
            <PercentageShower num={this.state.num}/>
          </div>
    

    我在input标签中加与不加 value属性,测试都可以。

    但是 PercentageApp 的重新渲染时,不传value进去,上次<input>标签中的数据怎么还存在?


  • 0
    administrators

    @enjoyit 把你完整代码贴一下


  • 0

    加删除线的部分,有没有都可以。

    class Input extends Component {
      handleChange(event){
        if(this.props.onSetNum){
          this.props.onSetNum(event.target.value);
        }
      }
      render () {
        return (
          <div>
            <input type='number' onChange={this.handleChange.bind(this)} ~~value={this.props.num}~~/>
          </div>
        )
      }
    }
    
    class PercentageShower extends Component {
      render () {
        let num=this.props.num*100;
        return (
          <div>{num.toFixed(2)+'%'}</div>
        )
      }
    }
    
    class PercentageApp extends Component {
      constructor(){
        super();
        this.state={
          num:0
        }
      }
      handleSetNum(num){
        this.setState({num:num});
      }
      render () {
        return (
          <div>
            <Input onSetNum={this.handleSetNum.bind(this)} ~~num={this.state.num}~~/>
            <PercentageShower num={this.state.num}/>
          </div>
        )
      }
    }
    

  • 0

    @胡子大哈
    代码如上


  • 0
    administrators

    @enjoyit 嗯,这里确实有点问题


  • 0

    class Input extends Component {
      
      constructor(){
        super()
        this.state={
          number:0
        }
      }
      
      inputClickHandle(event){  
        this.setState(
          {number:event.target.value},
          ()=>{
            if(this.props.onSubmit){
              const {number} = this.state
              this.props.onSubmit({number})
            }
          }
        )
      }
      
      render () {
        return (
          <div>
            <input type='number' onChange={this.inputClickHandle.bind(this)} />
          </div>
        )
      }
    }
    
    class PercentageShower extends Component {
      
      render () {
        return (
          <div>
            {this.props.number*100}%
          </div>
        )
      }
    }
    
    class PercentageApp extends Component {
      
      constructor(){
        super()
        this.state = {
          number:0
        }
      }
      
      parmHandle(number){
        this.setState(number)
      }
      
      render () {
        return (
          <div>
            <Input onSubmit={this.parmHandle.bind(this)} />
            <PercentageShower number={this.state.number} />
          </div>
        )
      }
    }
    

    Wrong Answer
    应该显示 85.29%, 但你显示的是 85.29389877113127%

    这是怎么回事?


  • 0
    administrators

    @Qinhua_Zhao 注意题目说的:

    例如 <Input /> 输入的是 0.1,那么就要显示 10.00%,保留两位小数。


  • 0

    @胡子大哈 QQQ


  • 0

    class Input extends Component {
      
      handleInput(e) {
        this.props.setNum(e.target.value);
      }
      
      render () {
        return <input onChange={this.handleInput.bind(this)} type='number' />;
      }
    }
    
    class PercentageShower extends Component {
      
      render () {
        var out = new Number(this.props.num);
        out = out*100;
        out = out.toFixed(2);
        return <div>{out}%</div>;
        
      }
    }
    
    class PercentageApp extends Component {
      
      constructor(props) {
        super(props);
        this.state = {
          value: 0
        };
      }
      
      handleInput (val) {
        this.setState( {value: val} );
      }
      
      render () {
        return (
          <div>
            <Input setNum={this.handleInput.bind(this)}/>
            <PercentageShower num={this.state.value}/>
          </div>
        )
      }
    }
    

  • 0

    
    class Input extends Component {
      handleOnChange(event) {
        this.props.setNum && this.props.setNum(event.target.value)
      }
    
      render() {
        return (
          <div>
            <input type="text"
                   onChange={this.handleOnChange.bind(this)} />
          </div>
        )
      }
    }
    
    class PercentageShower extends Component {
      static defaultProps = {
        percentage: 0
      }
      render() {
        let out = this.props.percentage
        return (
          <div>
            {out > 0 && out < 1 ? (out * 100).toFixed(2) : out}%
          </div>
        )
      }
    }
    
    class PercentageApp extends Component {
      constructor() {
        super()
        this.state = {
          num: 0
        }
      }
    
      handleInput(num) {
        this.setState({
          num: num
        })
      }
    
      render() {
        return (
          <div>
            <Input setNum={this.handleInput.bind(this)}/>
            <PercentageShower percentage={this.state.num} />
          </div>
        )
      }
    }
    

  • 0

    @enjoyit#9 百分比换算器 中说:

    个人觉得这Input里的 value 没有必要!因为数据直接由
    event.target.value 获取到传到父组件了,value的作用是可以初始化,input的值。这两者并没有直接的关系呀!


  • 0

    我在本地运转正确,但是上传失败,帮看下啥原因?谢谢
    下面是我的代码:

    class Input extends Component {
        handleInputChange(event){
            this.props.onSubmit(event.target.value)
        }
    
        render () {
            return (
                <div>
                    <input
                        type='number'
                        onChange={this.handleInputChange.bind(this)}
                    />
                </div>
            )
        }
    }
    
    class PercentageShower extends Component {
        static defaultProps  = {
            number:''
        }
    
    
        render () {
            return (
                <div>
                    <input
                        value={this.props.number}
                    />
                </div>
            )
        }
    }
    
    class PercentageApp extends Component {
        constructor(){
            super()
            this.state = {
                number:''
            }
        }
    
        handleNumber(number){
            //这段处理的很粗糙,有没有更标准的处理方法啊
            let numberStr = (number*100).toString()
            if (numberStr.indexOf(".")) {
                numberStr = parseFloat(numberStr).toFixed(2).toString() + "%"
            } else {
                numberStr  += ".00%"
            }
            this.setState({
                number : numberStr
            })
        }
    
        render () {
            return (
                <div>
                    <Input onSubmit={this.handleNumber.bind(this)} />
                    <PercentageShower number={this.state.number}/>
                </div>
            )
        }
    }
    

  • 0

    @popwalker 我找到原因了,PercentageShower中我return的是一个input,实际上我return的是div就通过了


  • 0

    class Input extends Component {
        render () {
            return (
                <div>
                    <input type='number' onChange={this.props.change}/>
                </div>
            )
        }
    }
    
    class PercentageShower extends Component {
        render () {
            return (
                <div>
                    {this.props.onShow}
                </div>
            )
        }
    }
    
    class PercentageApp extends Component {
        constructor () {
            super();
            this.state = {
                num: 0
            }
        }
    
        handleNumber (event) {
            let newNum = event.target.value*100;
            newNum = newNum.toFixed(2) + "%";
            this.setState({
                num: newNum
            })
        }
    
        render () {
            return (
                <div>
                    <Input change={this.handleNumber.bind(this)}/>
                    <PercentageShower onShow={this.state.num}/>
                </div>
            )
        }
    }
    
    

    @胡子大哈 大哈哥,你看看我写的 代码测试通过了,不过我受你状态提升思想的影响,什么都想放在父组件里,能麻烦你看看 我这个写法 有啥缺陷或者好处么? 哪里会建议我改一改呢?


  • 0

    class Input extends Component {
        constructor() {
            super()
            this.state = {
                value: ''
            }
        }
        handleChange=(e)=>{
            this.setState({
                value:e.target.value
            })
            if(this.props.onChange){
                this.props.onChange({value:e.target.value})
            }
        }
    
        render() {
            return (
                <div>
                    <input onChange={this.handleChange} value={this.state.value} type='number'/>
                </div>
            )
        }
    }
    
    class PercentageShower extends Component {
        render() {
            return (
                <div>
                    {this.props.value}
                </div>
            )
        }
    }
    
    class PercentageApp extends Component {
        constructor(){
            super()
            this.state={
                value:''
            }
        }
        handleChange = (value) => {
            console.log(value)
            if(!value) return
            if(!value.value) return
            let values = value.value*100
            this.setState({
                value:values.toFixed(2)+'%'
            })
        }
        render() {
            return (
                <div>
                    <Input onChange={this.handleChange}/>
                    <PercentageShower value={this.state.value}/>
                </div>
            )
        }
    }
    

  • 0
    administrators

    @fingertip 发布帖子的时候你的代码可以用 markdown 语法包裹起来,这样会看起来会好一些。


  • 0

    其实这个题目吧,用到toFixed都不准确,因为JS的浮点数精度问题,toFixed的四舍五入结果并不精准。。。。


  • 0

    @胡子大哈
    运行信息: 应该显示 85.59%, 但你显示的是 0.00%
    帮我看看,谢谢啦

    class Input extends Component {
      constructor(props){
        super(props)
        this.state = {
          num: 0
        }
      }
      inputChange(event){
        this.setState({
          num: event.target.value
        })
        this.props.onChange(this.state.num)
      }
      render () {
        return (
          <div>
            <input type='number' value={this.state.num} onChange={this.inputChange.bind(this)} />
          </div>
        )
      }
    }
    
    class PercentageShower extends Component {
      static defaultProps = {
        percentage: '00.00%'
      }
      render () {
        return (
          <div>{this.props.percentage}</div>
        )
      }
    }
    
    class PercentageApp extends Component {
      constructor(props){
        super(props)
        this.state = {
          percentage: ''
        }
      }
      ConvetPercent(num){
        const per = (parseFloat(num) * 100).toFixed(2)  + '%'
        this.setState({
          percentage: per
        })
      }
      render () {
        return (
          <div>
            <Input onChange={this.ConvetPercent.bind(this)}/>
            <PercentageShower percentage={this.state.percentage}/>
          </div>
        )
      }
    }
    

  • 0

    @huzidaha 大哈兄,没想明白哪里错了,在本地是OK的,但是一直报
    0_1498036944206_QQ20170621-172110@2x.png
    请教

    class Input extends Component {
      constructor(){
        super();
        this.state = {
          input:''
        }
      }
      render () {
        return (
          <div>
            <input type='number' 
                   onInput={(e)=>this.setState({input:e.target.value})}
            />
            <PercentageShower input={this.state.input}/>
          </div>
        )
      }
    }
    
    
    class PercentageShower extends Component {
      render () {
        function switchNumber(props){
          return (props*100).toFixed(2)+'%'
        }
        return (
          <div>{this.props.input && switchNumber(this.props.input)}</div>
        )
      }
    }
    class PercentageApp extends Component {
      render () {
        return <Input />
      }
    }
    

登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待