2016-09-16 1 views
1

Я играю arround с React and Material, и я блуждаю, как я могу передать переменную в ярлыке компонента Material UI?Разрешение переменной в материале UI RaisedButton Label

Вот мой код:

const LoginForm = ({ 
    myVariable 
}) => (
    {/*....*/} 
    <RaisedButton type="submit" label={myVariable} primary/> 
    {/*....*/} 
); 

LoginForm.propTypes = { 
    myVariable : PropTypes.string.isRequired 
}; 

export default LoginForm; 

Но, даже если метка правильно отображается в браузере (хром), консоль показывать это предупреждение:

warning.js:36 Warning: Failed prop type: Required prop label or children or icon was not specified in RaisedButton. 

Edit: После некоторой отладки возникает то, что представление визуализируется несколько раз (по крайней мере 4 раза ???), а в первом рендере myVariable не определен.

Итак, теперь мне нужно решить, почему компонент визуализируется в sevral раз и почему в первом рендере переменные не определены.

Итак, здесь мой код.

Base.jsx

import React, {PropTypes} from 'react'; 
import {Link, IndexLink} from 'react-router'; 

const Base = ({ 
    children 
}) => (
    <div> 
    <div className="top-bar"> 
    {children} 
    </div> 
); 

Base.propTypes = { 
    children: PropTypes.object.isRequired 
}; 

export default Base; 

Auth.js

class Auth { 

    /** 
    * Authenticate a user. Save a token string in Local Storage 
    * 
    * @param {string} token 
    */ 
    static authenticateUser(token) { 
    localStorage.setItem('token', token); 
    } 

    /** 
    * Check if a user is authenticated - check if a token is saved in Local Storage 
    * 
    * @returns {boolean} 
    */ 
    static isUserAuthenticated() { 
    return localStorage.getItem('token') !== null; 
    } 

    /** 
    * Deauthenticate a user. Remove a token from Local Storage. 
    * 
    */ 
    static deauthenticateUser() { 
    localStorage.removeItem('token'); 
    } 

    /** 
    * Get a token value. 
    * 
    * @returns {string} 
    */ 

    static getToken() { 
    return localStorage.getItem('token'); 
    } 
} 

export default Auth; 

loginForm.jsx

import React, {PropTypes} from 'react'; 
import {Link} from 'react-router'; 
import {Card, CardText} from 'material-ui/Card'; 
import RaisedButton from 'material-ui/RaisedButton'; 
import TextField from 'material-ui/TextField'; 

const LoginForm = ({ 
    locales, 
    onSubmit, 
    onChange, 
    errors, 
    successMessage, 
    user 
}) => (
    <Card className="container"> 
    <form action="/" onSubmit={onSubmit}> 
     <h2 className="card-heading">{locales.connect_to_your_account}</h2> 

     {successMessage && <p className="success-message">{successMessage}</p>} 
     {errors.summary && <p className="error-message">{errors.summary}</p>} 

     <div className="field-line"> 
     <TextField 
      floatingLabelText={locales.email} 
      name="email" 
      errorText={errors.email} 
      onChange={onChange} 
      value={user.email} 
     /> 
     </div> 

     <div className="field-line"> 
     <TextField 
      floatingLabelText={locales.password} 
      type="password" 
      name="password" 
      onChange={onChange} 
      errorText={errors.password} 
      value={user.password} 
     /> 
     </div> 

     <div className="button-line"> 
     <RaisedButton type="submit" label={locales.log_in} primary/> 
     </div> 

     <CardText>{locales.dont_have_account_yet} <Link to={'/request-account'}>{locales.request_one}</Link>.</CardText> 
    </form> 
    </Card> 
); 

LoginForm.propTypes = { 
    locales  : PropTypes.object.isRequired, 
    onSubmit  : PropTypes.func.isRequired, 
    onChange  : PropTypes.func.isRequired, 
    errors  : PropTypes.object.isRequired, 
    successMessage: PropTypes.string.isRequired, 
    user   : PropTypes.object.isRequired 
}; 

export default LoginForm; 

loginPage.jsx

import React, {PropTypes} from 'react'; 
import Auth from '../modules/Auth'; 
import LoginForm from '../components/LoginForm.jsx'; 

class LoginPage extends React.Component { 

    /** 
    * Class constructor. 
    */ 
    constructor(props, context) { 
    super(props, context); 

    const storedMessage = localStorage.getItem('successMessage'); 
    let successMessage = ''; 

    if (storedMessage) { 
     successMessage = storedMessage; 
     localStorage.removeItem('successMessage'); 
    } 

    // set the initial component state 
    this.state = { 
     locales: {}, 
     errors : {}, 
     successMessage, 
     user : { 
     email : '', 
     password: '', 
     }, 
    }; 

    this.processForm = this.processForm.bind(this); 
    this.changeUser = this.changeUser.bind(this); 
    } 

    // Load translations via an Api Rest 
    componentDidMount() { 
    const data = { 
     connect_to_your_account: {}, 
     log_in     : {}, 
     email     : {}, 
     password    : {}, 
     dont_have_account_yet : {}, 
     request_one   : {}, 
    }; 
    const xhr = new XMLHttpRequest(); 
    xhr.open('post', '/app_test.php/api/fr/translations'); 
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); 

    xhr.responseType = 'json'; 
    xhr.addEventListener('load',() => { 
     if (xhr.status === 200) { 
     this.setState({ 
      locales: xhr.response, 
     }); 
     } 
    }); 
    xhr.send(JSON.stringify(data)); 
    } 

    /** 
    * Process the form. 
    * 
    * @param {object} event - the JavaScript event object 
    */ 
    processForm(event) { 
    // prevent default action. in this case, action is the form submission event 
    event.preventDefault(); 

    // create a base64 encoded string 
    const credentials = window.btoa(`${this.state.user.email}:${this.state.user.password}`); 

    // create an AJAX request 
    const xhr   = new XMLHttpRequest(); 
    xhr.withCredentials = true; 
    xhr.open('post', '/app_test.php/api/fr/tokens'); 
    xhr.setRequestHeader('authorization', `Basic ${credentials}`); 

    xhr.responseType = 'json'; 
    xhr.addEventListener('load',() => { 
     if (xhr.status === 201) { 
     // success 

     // change the component-container state 
     this.setState({ 
      errors: {} 
     }); 

     // save the token 
     Auth.authenticateUser(xhr.response.token); 

     // change the current URL to/
     this.context.router.replace('/'); 
     } else { 
     // failure 

     // change the component state 
     const errors = xhr.response.errors ? xhr.response.errors : {}; 
     errors.summary = xhr.response.message; 

     this.setState({ 
      errors 
     }); 
     } 
    }); 
    xhr.send(null); 
    } 

    /** 
    * Change the user object. 
    * 
    * @param {object} event - the JavaScript event object 
    */ 
    changeUser(event) { 
    const field = event.target.name; 
    const user = this.state.user; 
    user[field] = event.target.value; 

    this.setState({ 
     user 
    }); 
    } 

    /** 
    * Render the component. 
    */ 
    render() { 
    return (
     <LoginForm 
     locales={this.state.locales} 
     onSubmit={this.processForm} 
     onChange={this.changeUser} 
     errors={this.state.errors} 
     successMessage={this.state.successMessage} 
     user={this.state.user} 
     /> 
    ); 
    } 

} 

LoginPage.contextTypes = { 
    router: PropTypes.object.isRequired 
}; 

export default LoginPage; 

routes.js

import Basepage from './containers/BasePage.jsx'; 
import LoginPage from './containers/LoginPage.jsx'; 
import Auth from './modules/Auth'; 

const routes = { 
    // base component (wrapper for the whole application). 
    component : Basepage, 
    childRoutes: [ 

    { 
     path  : '/', 
     getComponent: (location, callback) => { 
     if (Auth.isUserAuthenticated()) { 
      callback(null, DashboardPage); 
     } else { 
      callback(null, LoginPage); 
     } 
     } 
    }, 

    { 
     path  : '/login', 
     component: LoginPage 
    }, 

    { 
     path : '/logout', 
     onEnter: (nextState, replace) => { 
     Auth.deauthenticateUser(); 

     // change the current URL to/
     replace('/'); 
     } 
    } 

    ] 
}; 

export default routes; 

index.js (Acces точка)

import React from 'react'; 
import ReactDom from 'react-dom'; 
import injectTapEventPlugin from 'react-tap-event-plugin'; 
import getMuiTheme from 'material-ui/styles/getMuiTheme'; 
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 
import {browserHistory, Router} from 'react-router'; 
import routes from './routes.js'; 

import '../styles/main.scss'; 

// remove tap delay, essential for MaterialUI to work properly 
injectTapEventPlugin(); 

ReactDom.render((
    <MuiThemeProvider muiTheme={getMuiTheme()}> 
    <Router history={browserHistory} routes={routes}/> 
    </MuiThemeProvider>), document.getElementById('app') 
); 

Переменные я пытаюсь отправить мнения переводимые текст, извлекаемые с помощью Api Rest (переводы управляется бэкэнд)

Спасибо за любую помощь.

+0

вы code isn't valid .. насколько я знаю, это должно быть 'primary = {true}'. Каково содержание 'myVariable'? –

+0

исправил код для установки primary = {true}, и он ничего не изменит. myVariable - это просто некоторая случайная строка. –

+0

Насколько я знаю, 'prop = {true}' и просто 'prop' эквивалентны и оба действительны. – Waiski

ответ

0

я наконец-то нашел workarround, не знаю, если ее лучшая практика или нет:

label={`${myVariable}`} 
+0

это не так. Если вы просто сделаете 'label =" myLabel "' ошибка ушла или? –

+0

Да, если я использую 'label =" myLabel "', ошибка исчезла, но я не хочу напрямую устанавливать текст, я хочу переменный текст. Как я могу это сделать, используя наилучшие прайсы React? Благодарю. –

+0

Я подумал об этом, потому что все, что вы делаете в своем ответе, это выполнить требование propType для строки.Может быть, 'myVariable'' undefined' на первом 'render'? Вы действительно должны добавить свой полный код! –

0

Вы можете попробовать с defaultProps, myVariable может быть undefined на первой визуализации

LoginForm.defaultProps= { 
    myVariable: "", 
}; 
+0

Да, это похоже на el solo lobo. Но теперь я хочу знать, почему существует много рендеринга (не менее 4 на странице входа). Я добавил полный код в исходный вопрос. Еще раз спасибо. –

Смежные вопросы