私はリアクションとマテリアルでarroundを再生していますが、マテリアルUIコンポーネントのラベルに変数を渡す方法はありますか?編集Material UI RaisedButton Labelで変数を許可する
warning.js:36 Warning: Failed prop type: Required prop label or children or icon was not specified in RaisedButton.
:は
const LoginForm = ({
myVariable
}) => (
{/*....*/}
<RaisedButton type="submit" label={myVariable} primary/>
{/*....*/}
);
LoginForm.propTypes = {
myVariable : PropTypes.string.isRequired
};
export default LoginForm;
しかし、ラベルはブラウザ(クロム)で正しく表示されても、コンソールは私にこの警告を表示:ここで
は私のコードです 一部のデバッグ後、ビューが複数回(少なくとも4回)表示され、1番目のレンダリングではmyVariableが未定義になります。
ここで、コンポーネントが何回連続してレンダリングされるのか、第1レンダリングで変数が定義されない理由を管理する必要があります。
ここに私のコード。
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;
(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経由で残りのテキストを翻訳検索されindex.js(翻訳バックエンドによって管理されます)
ありがとうございました。
にあなたのレンダリングに
undefined
かもしれませんコードは有効ではありません。私が知っている限り、 'primary = {true}'でなければなりません。 'myVariable'の内容は何ですか? –プライマリ= {true}を設定するコードが修正され、何も変更されません。 myVariableはランダムな文字列です。 –
私が知っている限り、 'prop = {true}'と 'prop'だけは同等であり、どちらも有効です。 – Waiski