2016-10-27 54 views
2

我是全新的React/Redux和作品,所以請原諒任何天真的假設/問題在這裏...Redux-Form和React-RTE - 保存RTE editorValue以形成狀態?

我已經設法在入職流程中取得了很大的進展我正在建設對於我的應用感謝redux-form的文檔 - 這是一個很棒的圖書館!

但是,我現在遇到了一些問題,因爲我試圖將一個React-RTE實例(https://github.com/sstur/react-rte)作爲自定義Field組件傳遞。我一直在關注文檔here。到目前爲止,我已經能夠渲染RTE並將editorValue prop記錄到控制檯,但是我無法獲取表單值來保存表單狀態。我要求將這個問題作爲一個關於redux-form gitrepo的問題發佈,但是也可以在這裏發佈,因爲其他人可能會遇到自定義字段組件的問題。任何幫助將非常感激!

這是我一直在嘗試與代碼:

我的Form容器(RoleForm.jsx) - 片段中的問題是JDEditor:

import React, {Component, PropTypes} from 'react'; 
import { connect } from 'react-redux' 
import { Field, reduxForm, formValueSelector } from 'redux-form' 
import validate from './validate.jsx' 
import renderField from './renderField.jsx' 
import JDEditor from './JDEditor.jsx' 

const renderError = ({ meta: { touched, error } }) => touched && error ? 
    <span>{error}</span> : false 

class RoleForm extends React.Component { 
    constructor(props) { 
     super(props); 
    } 

    handleChange(editorValue){ 
     console.log("CHANGE | EditorValue: " + editorValue) 
    } 

    handleBlur(editorValue){ 
     console.log("BLUR | EditorValue: " + editorValue) 
    } 

    handleFocus(editorValue){ 
     console.log("FOCUS | EditorValue: " + editorValue) 
    } 

    render(){ 
    let { handleSubmit, previousPage, company, value} = this.props 

    return (
     <div className="login-wrapper"> 
     <div className="form" style={{borderRadius:4, margin:'0 auto', padding:24, maxWidth:780}}> 
     <h3 style={{fontWeight:700}}>Role Details</h3> 
     <p>Here's what we were able to pull:</p> 
     <form onSubmit={handleSubmit}> 
      <div style={{width:'50%', display:'inline-block'}}><Field name="role" type="text" component={renderField} label="Role"/></div> 
      <div style={{width:'50%', display:'inline-block'}}><Field name="role_url" type="url" component={renderField} label="Role Link"/></div> 
      <div style={{width:'85%', display:'inline-block', borderBottom:'1px solid'}}></div> 
      <label style={{display:'block', textAlign:'left', paddingLeft:'8px'}}>Role Description</label> 
      <div style={{display:'inline-block', width:'100%', padding:'0px 8px 8px 8px'}}> 
      <Field name="role_description" 
      component={props=><JDEditor format={'html'} value={{rte_value:props.editorValue}} onFocus={this.handleFocus.bind(this)} onBlur={this.handleBlur.bind(this)} onChange={this.handleChange.bind(this)} {...props} />} /> 
      </div> 
     <div style={{marginTop:'10px', clear:'both'}}> 
      <button type="button" className="btn btn-default" style={{width:'100px', marginRight:'4px'}} onClick={previousPage}>Back</button> 
      <button type="submit" className="btn btn-primary" style={{width:'100px'}}>Continue</button> 
     </div> 
     </form> 
     </div> 
     <div style={{padding:'100%', background:'#f7f7f7'}}> 
     </div> 
     </div> 
    ) 
    } 
} 

export default RoleForm = reduxForm({ 
    form: 'onboarding', 
    destroyOnUnmount: false, 
    validate 
})(RoleForm) 

而JDEditor類:

import React, {Component} from 'react'; 
import RichTextEditor, {createEmptyValue} from 'react-rte'; 
import autobind from 'class-autobind'; 

import type {EditorValue} from 'react-rte'; 

type Props = { 
    value: string; 
    format: string; 
    onChange: (value: string) => any; 
}; 
type State = { 
    editorValue: EditorValue; 
}; 

export default class JDEditor extends Component { 
    props: Props; 
    state: State; 
    // The [format, value] of what's currently displayed in the  <RichTextEditor /> 
    _currentValue: ?[string, string]; 

    constructor() { 
    super(...arguments); 
    autobind(this); 
    this.state = { 
     editorValue: createEmptyValue(), 
    }; 
    } 

    componentWillMount() { 
    this._updateStateFromProps(this.props); 
    } 

    componentWillReceiveProps(newProps: Props) { 
    this._updateStateFromProps(newProps); 
    } 

    _updateStateFromProps(newProps: Props) { 
    let {value, format} = newProps; 
    if (this._currentValue != null) { 
     let [currentValue, currentFormat] = this._currentValue; 
     if (format === currentFormat && value === currentValue) { 
     return; 
     } 
    } 
    let {editorValue} = this.state; 
    this.setState({ 
     editorValue: editorValue.setContentFromString(value, format), 
    }); 
    this._currentValue = [format, value]; 
    } 

    render() { 
    let {value, format, onChange, ...otherProps} = this.props; // eslint-disable-line no-unused-vars 
    return (
     <RichTextEditor 
     {...otherProps} 
     value={this.state.editorValue} 
     onChange={this._onChange} 
     /> 
    ); 
    } 

    _onChange(editorValue: EditorValue) { 
    let {format, onChange} = this.props; 
    let oldEditorValue = this.state.editorValue; 
    this.setState({editorValue}); 
    let oldContentState = oldEditorValue ?  oldEditorValue.getEditorState().getCurrentContent() : null; 
    let newContentState = editorValue.getEditorState().getCurrentContent(); 
    if (oldContentState !== newContentState) { 
     let stringValue = editorValue.toString(format); 
     // Optimization so if we receive new props we don't need 
     // to parse anything unnecessarily. 
     this._currentValue = [format, stringValue]; 
     if (onChange && stringValue !== this.props.value) { 
     onChange(stringValue); 
     } 
    } 
    } 
} 

回答

3

這就是我已經做到的。我想在降價內容:

// in client side entry file 
import RichTextEditor from 'react-rte' 

window.RichTextEditor = RichTextEditor 

然後組件是RichTextMarkdown.js

+1

美麗!非常感謝。如果你不介意,你能否詳細說明我的嘗試邏輯中的錯誤,以便我能夠學習?無論如何,再次感謝你! – KenRambo