javascript - 通过 state.value ReactJS 将 textarea 值复制到新组件

标签 javascript reactjs

我对 React 很陌生...因此,我在将用户在文本区域中输入的字符串复制到新组件时遇到了麻烦:如果我不创建另一个 Card ,我可以维护该值组件,但是当我创建一个新的 Card 时组件,该组件应该为空,该值也会在那里捕获。我尝试过通过状态跟踪值和以前的内容,但是 setState()不会将新值更新为空字符串。

import React, { Component } from 'react';
import './style.css';

const list = [
  {
    id : 0,
    title : "Went well",
    showCard : false,
    addCard : (func0,func1,func2,func3,func4,color,value)=> {
      let id = "x"+count++
      let myProps = {id:id,deleteCard:func0,handleChange:func1,moveRight:func2,moveLeft:func3,setText:func4,key:id,color:color,value:value}
      return <Card {...myProps}/>},
    cards : [],
    color : "pink"
  },
  {
    id : 1,
    title : "To Improve",
    showCard : false,
    addCard : (func0,func1,func2,func3,func4,color,value)=> {
      let id = "y"+count++
      let myProps = {id:id,deleteCard:func0,handleChange:func1,moveRight:func2,moveLeft:func3,setText:func4,key:id,color:color,value:value}
      return <Card {...myProps}/>},
    cards : [],
    color : "yellow"
  },
  {
    id : 2,
    title : "Action Items",
    showCard : false,
    addCard : (func0,func1,func2,func3,func4,color,value)=> {
      let id = "z"+count++
      let myProps = {id:id,deleteCard:func0,handleChange:func1,moveRight:func2,moveLeft:func3,setText:func4,key:id,color:color,value:value}
      return <Card {...myProps}/>},
    cards : [],
    color : "blue"
  }
]

let count = 0

class App extends Component {
  constructor(){
    super()
    this.state = {list : list, value: "", current: "",}
    this.buttonClick = this.buttonClick.bind(this)
    this.deleteCard = this.deleteCard.bind(this)
    this.handleChange = this.handleChange.bind(this)
    this.moveRight = this.moveRight.bind(this)
    this.moveLeft = this.moveLeft.bind(this)
    this.setText = this.setText.bind(this)
  }

  buttonClick(ev,id,func0,func1,func2,func3,func4){
    let a0 = null
    this.setState({current:""})
    for(let obj of this.state.list){
      if(obj.id === id){ 
        console.log("here af")
        a0 = obj.addCard(func0,func1,func2,func3,func4,obj.color,this.state.value)
        obj.cards.push(a0)
      }

    }

    this.setState({list:this.state.list})
  }

  moveLeft(ev,id,func0,func1,func2,func3,func4){
    ev.preventDefault()
    let a0 = null

    if(this.state.value === this.state.current) this.setState({value:this.state.current})

    let updatedList = this.state.list.map((obj)=>{
      let found = obj.cards.findIndex((element)=> element.key === id)

      if(obj.id === 0){
         if(found !== -1){
          obj.cards.splice(found,1)
          a0 = this.state.list[2].addCard(func0,func1,func2,func3,func4,this.state.list[2].color,this.state.value)
          this.state.list[2].cards.push(a0)     
        }
      }

      if(obj.id === 1){
        if(found !== -1){
          obj.cards.splice(found,1)
          a0 = this.state.list[0].addCard(func0,func1,func2,func3,func4,this.state.list[0].color,this.state.value)
          this.state.list[0].cards.push(a0)     
        }
      }

      if(obj.id === 2){
        if(found !== -1){
          obj.cards.splice(found,1)
          a0 = this.state.list[1].addCard(func0,func1,func2,func3,func4,this.state.list[1].color,this.state.value)
          this.state.list[1].cards.push(a0)    
        }
      }

      return obj
    })

    this.setState({list:updatedList,})
  }

  moveRight(ev,id,func0,func1,func2,func3,func4){
    ev.preventDefault()
    let a0 = null

    let updatedList = this.state.list.map((obj)=>{
      let found = obj.cards.findIndex((element)=> element.key === id)

      if(obj.id === 0){
        if(found !== -1){
          obj.cards.splice(found,1)
          a0 = this.state.list[1].addCard(func0,func1,func2,func3,func4,this.state.list[1].color,this.state.value)
          this.state.list[1].cards.push(a0)     
        }
      }

      if(obj.id === 1){
        if(found !== -1){
          obj.cards.splice(found,1)
          a0 = this.state.list[2].addCard(func0,func1,func2,func3,func4,this.state.list[2].color,this.state.value)
          this.state.list[2].cards.push(a0)     
        }
      }

      if(obj.id === 2){
        if(found !== -1){
          obj.cards.splice(found,1)
          a0 = this.state.list[0].addCard(func0,func1,func2,func3,func4,this.state.list[0].color,this.state.value)
          this.state.list[0].cards.push(a0)    
        }
      }

      return obj
    })
    this.setState({list:updatedList,})
  }

  setText(ev){
    this.setState({value:ev.target.value,current:ev.target.value})
  }

  deleteCard(ev,id){
    ev.preventDefault()
    let updatedList = this.state.list.map((obj)=>{
      let found = obj.cards.findIndex((element)=> element.key === id)
      if(found !== -1)
        obj.cards.splice(found,1)
      return obj
    })
    this.setState({list:updatedList})
  }

  handleChange(ev){
    this.setState({value:ev.target.value,current:ev.target.value})
  }

  render() {
    return (
      <div className="App">
        <h2>Retro Board</h2>
          <ul className="container">
            {this.state.list.map((item) =>
                <Contak key={item.title+item.id} text={item.title} buttonClick={this.buttonClick} deleteCard={this.deleteCard} handleChange={this.handleChange} moveRight={this.moveRight} moveLeft={this.moveLeft} setText={this.setText} showCard={item.showCard} id={item.id} cards={item.cards} />
            )}
         </ul>
      </div>
    )
  }
}

function Contak(props){
  return <li>
          <h3>{props.text}</h3>
          <ul className="stack">
            <li><button id={props.text} type="button" className="block" onClick={e =>props.buttonClick(e,props.id,props.deleteCard,props.handleChange,props.moveRight,props.moveLeft,props.setText)}>+</button></li>
            {props.cards.map((card)=> {
              console.log("card",card)
              return card || null
              })}
          </ul>
          </li>
}

function Card(props){
  return <li>
          <div className="card" style={{backgroundColor: props.color}}>
            <textarea type="text" className="card" placeholder="Enter text here" defaultValue={props.value} onChange={e =>props.handleChange(e)} onBlur={e => props.setText(e)}></textarea>
            <div><a className="ltCtl" href="./logo" onClick={e=>props.moveLeft(e,props.id,props.deleteCard,props.handleChange,props.moveRight,props.moveLeft,props.setText)}>&lt;</a><a className="clCtl" href="./logo" onClick={e =>props.deleteCard(e,props.id)}>x</a><a className="rtCtl" href="./logo" onClick={e =>props.moveRight(e,props.id,props.deleteCard,props.handleChange,props.moveRight,props.moveLeft,props.setText)}>&gt;</a></div>
          </div>
         </li>
}

export default App;

感谢任何帮助。

J.

最佳答案

您设置的状态未被触发,因为您没有在文本区域正确使用 onChange 属性。您需要这样设置:

handleChange(ev){
   this.setState({value:ev.target.value,current:ev.target.value})
 }
...
<textarea type="text" onChange={e =>props.handleChange.bind(this)}></textarea>

handleChange 中的 .bind(this) 告诉 onChange 在事件触发时运行该函数。如果您实际上像上面的代码中那样调用该函数onChange={e =>props.handleChange(e)},那么该函数会立即计算一次,但不会再次计算。

考虑这个问题的最好方法是采用 JS:

function foo(){
    return 5
}

var bar_now = foo() //the way you have set it up, but not what you want.
  >> 5

var bar_later = foo //the way you want it set up
  >> foo
bar_later() //when you evaluate bar_later() it calls foo()
  >> 5

关于javascript - 通过 state.value ReactJS 将 textarea 值复制到新组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53035236/

相关文章:

javascript - react-native Swiper 在模态中是空白的

reactjs - 将部分文本作为链接。( react - 本地化)

reactjs - Jest 和 Enzyme 测试带有 ES6 Arrow 函数的 React 组件

javascript - D3不更新数据

javascript - 如何获取/读取 Chrome 中关于 :flags? 的标志值

javascript - 使用 Javascript 从 API 检索数据

css - Next.js 样式 - 页脚组件出于某种原因不在屏幕底部?

javascript - 在 React/React Native (redux) 中使用展开运算符

reactjs - 共享组件库最佳实践

javascript - 如何将命名参数传递给 phantomjs 文件