Forms 如何在redux中更改输入值

Forms 如何在redux中更改输入值,forms,reactjs,input,ecmascript-6,redux,Forms,Reactjs,Input,Ecmascript 6,Redux,我正在基于react-redux制作一个文件管理器应用程序,我遇到了输入问题 例如,我的代码: PathForm.js: export default class PathForm extends Component { render() { const { currentPath, handleSubmit } = this.props; console.log('PathFormPathFormPathForm', this.props) return (

我正在基于react-redux制作一个文件管理器应用程序,我遇到了输入问题

例如,我的代码:

PathForm.js:

export default class PathForm extends Component {

  render() {

    const { currentPath,  handleSubmit } = this.props;
    console.log('PathFormPathFormPathForm', this.props)

    return (
      <div className="path-box">
        <form onSubmit={handleSubmit}>
          <div>
            <input type="text" className="current-path-input" placeholder="input path"  value={currentPath} />
          </div>
          <button className="go-btn" type="submit">Go</button>
        </form>
      </div>
    );
  }
}
导出默认类PathForm扩展组件{
render(){
const{currentPath,handleSubmit}=this.props;
console.log('pathFormPathForm',this.props)
返回(
去
);
}
}
Explorer.js:

class Explorer extends Component {

  goPath(e) {
    e.preventDefault()
    // fake function here, because I have to solve the input problem first
    console.log('PathForm goPath:',this.props)
    let {targetPath , actions} = this.props
    swal(targetPath)
  }

  render() {
    const { node, currentPath , actions} = this.props
    console.log('Explorer.render:',this.props)

    return (
      <div className='explorer-container'>
        <PathForm currentPath={currentPath} handleSubmit={this.goPath.bind(this)}/>
        <FileListOperator />
        <FileListView fileList={node && node.childNodes} actions ={actions} />
      </div>
    );
  }
}


function mapStateToProps(state, ownProps) {
  return {
    node: state.tree[state.tree.currentPath],
    currentPath: state.tree.currentPath
  };
}

function mapDispatchToProps(dispatch) {
  console.log('mapDispatchToProps')
  return {
    actions: bindActionCreators(NodeActions, dispatch)
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Explorer);
类资源管理器扩展组件{
戈帕斯(e){
e、 预防默认值()
//这里的假函数,因为我必须先解决输入问题
console.log('PathForm goPath:',this.props)
让{targetPath,actions}=this.props
swal(目标路径)
}
render(){
const{node,currentPath,actions}=this.props
console.log('Explorer.render:',this.props)
返回(
);
}
}
函数mapStateToProps(状态,ownProps){
返回{
节点:state.tree[state.tree.currentPath],
currentPath:state.tree.currentPath
};
}
功能图DispatchToprops(调度){
console.log('mapDispatchToProps')
返回{
操作:bindActionCreators(节点操作、调度)
};
}
导出默认连接(
MapStateTops,
mapDispatchToProps
)(探索者);
我想要的功能:

我有一个
路径表单
,它需要从两个方向显示路径:

  • 用户从左树状视图中单击文件路径,
    Explorer
    将此路径作为
    currentPath
    获取,然后传递到
    PathForm
    ,并在输入中显示
    currentPath

  • 用户直接键入路径到
    PathForm
    的输入,
    PathForm
    调用
    handleSubmit
    (资源管理器的功能)以更改
    当前路径

    附加:我想将
    PathForm
    保留为无状态组件

  • 问题

  • 我想将
    PathForm
    用作无状态表单,因此我不想将其连接到存储,但我需要它通过
    currentPath
    更改输入。但若我设置了
    value={currentPath}
    ,用户就不能键入任何其他内容
  • 更改为
    允许在此输入中输入用户类型字符串,但不能使用
    资源管理器传递的道具
    currentPath
  • 我能想象的唯一方法就是将这个表单连接到我不想要的存储。我想
    Explorer
    分派所有动作并传递道具

  • 尝试了一些软件包

    我发现输入与我的想法不符,因此我尝试了两种流行的软件包:

  • redux表单

    它创建表单需要这么多代码,而官方文档没有说明如何使用父道具呈现此表单, 我试着向它传递
    道具
    handleSubmit
    ,而不是工作。等我看到 及 我发现我不能这样做,它定义了一些函数覆盖我的函数,这种行为对我不好(我必须更改handlerSubmit函数名,但它仍然不起作用),并且它连接到存储。所以我转向
    formsy react

  • formsy react

    尽管它提供了一些
    mixin
    ,但它仍然需要很多代码,但我仍然需要自己编写一个带有
    changeValue
    函数的自定义文本输入(
    changeValue
    在大多数情况下,在编写普通
    html jquery应用程序时不需要)。然后我发现问题是
    PathForm
    无法使用
    Explorer
    传递的道具
    currentPath

  • 可能是有效的解决方案(但我不倾向于使用):

    连接
    PathForm
    以存储,为此输入添加另一个状态
    inputPathValue
    。使用
    inputPathValue
    currentPath


    在上面,我发现使用输入/表单在反应中非常方便。。。。 这是否意味着我必须将
    PathForm
    连接到stroe?
    有没有其他方法可以解决我的问题?

    在reactjs中有
    不受控的
    (非设定值)和
    受控的
    (设定值)输入

    受控
    不允许用户输入,但
    非受控
    允许用户输入

    解决方案:

  • 需要使用
    非受控输入
    (无值属性)
  • 选择输入元素并在
    currentPath
    更改时设置值

  • 坏方法:

    代码:

    2.使用按钮单击

    export default class PathForm extends Component {
    
      constructor(props) {
        super(props)
        // can not find `this` if not bind
        this.handleGoClick = this.handleGoClick.bind(this)
        this.handleKeyUp = this.handleKeyUp.bind(this)
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.currentPath !== this.props.currentPath) {
          this.setInputValue(nextProps.currentPath)
        }
      }
    
      getInputValue() {
        return this.refs.pathInput.value
      }
    
      setInputValue(val) {
        this.refs.pathInput.value = val
      }
    
      handleKeyUp(e) {
        if (e.keyCode === 13) {
          this.handleGoClick()
        }
      }
    
      handleGoClick(e) {
        e.preventDefault()
        this.props.handleSubmit(this.getInputValue())
      }
    
      render() {
    
        return (
          <div className="path-box">
            <form >
              <input className="current-path-input"
              defaultValue={this.props.currentPath}
              onKeyUp={this.handleKeyUp}
              ref="pathInput" />
              <button className="waves-effect waves-light btn"  type="submit" onClick={this.handleGoClick}>Go</button>
            </form>
          </div>
        );
      }
    }
    
    导出默认类PathForm扩展组件{
    建造师(道具){
    超级(道具)
    //如果未绑定,则找不到'this'
    this.handleGoClick=this.handleGoClick.bind(this)
    this.handleKeyUp=this.handleKeyUp.bind(this)
    }
    组件将接收道具(下一步){
    if(nextrops.currentPath!==this.props.currentPath){
    此.setInputValue(nextProps.currentPath)
    }
    }
    getInputValue(){
    返回this.refs.pathInput.value
    }
    设置输入值(val){
    this.refs.pathInput.value=val
    }
    handleKeyUp(e){
    如果(如keyCode===13){
    this.handleGoClick()
    }
    }
    手杖(e){
    e、 预防默认值()
    this.props.handleSubmit(this.getInputValue())
    }
    render(){
    返回(
    去
    );
    }
    }
    
    如果您确实不想在Redux中存储状态,可以使用
    setState
    将状态存储在组件上。强烈反对直接访问输入。您应该跟踪组件上输入的状态。在输入中添加一个
    onChange
    处理程序,存储状态并处理
    componentWillReceiveProps
    ,在这里您可以决定如何处理新传入的props

    export default class PathForm extends Component {
    
      constructor(props) {
        super(props)
        // can not find `this` if not bind
        this.handleSubmit = this.handleSubmit.bind(this)
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.currentPath !== this.props.currentPath) {
          this.setInputValue(nextProps.currentPath)
        }
      }
    
      getInputValue() {
        return this.refs.pathInput.value
      }
    
      setInputValue(val) {
        this.refs.pathInput.value = val
      }
    
      handleSubmit(e){
        e.preventDefault()
        this.props.handleSubmit(this.getInputValue())
      }
    
      render() {
    
        return (
          <div className="path-box">
            <form onSubmit={this.handleSubmit}>
              <input className="current-path-input"
              defaultValue={this.props.currentPath}
              ref="pathInput" />
              <button className="waves-effect waves-light btn"  type="submit">Go</button>
            </form>
          </div>
        );
      }
    }
    
    export default class PathForm extends Component {
    
      constructor(props) {
        super(props)
        // can not find `this` if not bind
        this.handleGoClick = this.handleGoClick.bind(this)
        this.handleKeyUp = this.handleKeyUp.bind(this)
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.currentPath !== this.props.currentPath) {
          this.setInputValue(nextProps.currentPath)
        }
      }
    
      getInputValue() {
        return this.refs.pathInput.value
      }
    
      setInputValue(val) {
        this.refs.pathInput.value = val
      }
    
      handleKeyUp(e) {
        if (e.keyCode === 13) {
          this.handleGoClick()
        }
      }
    
      handleGoClick(e) {
        e.preventDefault()
        this.props.handleSubmit(this.getInputValue())
      }
    
      render() {
    
        return (
          <div className="path-box">
            <form >
              <input className="current-path-input"
              defaultValue={this.props.currentPath}
              onKeyUp={this.handleKeyUp}
              ref="pathInput" />
              <button className="waves-effect waves-light btn"  type="submit" onClick={this.handleGoClick}>Go</button>
            </form>
          </div>
        );
      }
    }