TODOListサンプルコードを参考にしながら、ajaxを呼ぶのを書いてみる。
プロジェクトはcreate-react-appを使用して作成する
create-react-app Test
cd ./Test
npm install --save redux
npm install --save jquery
npm install --save material-ui@1.0.0-beta.30
とりあえず適当なjson形式のファイルをajaxで取得して表示するようなのを書いてみました。
自動生成されたindex.jsを書き換えていきます。
本来なら機能ごとにファイル分割するべきですが、
まずは動作確認用なので1ファイルで全部書いてしまいます。
material-uiで少し見た目もよくしてみた
index.js
import React from 'react';
import {render} from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import { createStore } from 'redux';
import $ from 'jquery';
import Reboot from 'material-ui/Reboot';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import Typography from 'material-ui/Typography';
import Button from 'material-ui/Button';
import Checkbox from 'material-ui/Checkbox';
import List, {ListItem, ListItemText} from 'material-ui/List';
import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table';
const initialState = {
tasks: []
};
function tasksReducer(state = initialState, action){
switch(action.type){
case 'INPUT_TASK':
return {
...state,
task : action.payload.task
}
case 'ADD_TASK':
return{
...state,
tasks: state.tasks.concat([action.payload.task])
};
default:
return state;
}
}
const store = createStore(tasksReducer);
const addTask = (task) => ({
type:'ADD_TASK',
payload:{
task,
}
});
function TodoApp({ store }){
const { tasks } = store.getState();
return (
<div>
<Reboot />
<AppBar position="static">
<Toolbar style={{backgroundColor: '#ffd699',}}>
<Typography type="title" color="inherit" style={{color:"white"}}>
Sample
</Typography>
</Toolbar>
</AppBar>
<div style={{padding:'16px'}} />
<Button raised color="primary" type="button" onClick={() => clickButton()}>実行</Button>
<Table>
<TableHead>
<TableRow>
<TableCell>#</TableCell>
<TableCell numeric>No.</TableCell>
<TableCell numeric>menu</TableCell>
</TableRow>
</TableHead>
<TableBody>
{
tasks.map(function(item,i){
return (
<TableRow key={i}>
<TableCell style={{width:'48px'}}>
<Checkbox/>
</TableCell>
<TableCell>{i}</TableCell>
<TableCell numeric>{`${item}`}</TableCell>
</TableRow>
);
})
}
</TableBody>
</Table>
</div>
);
}
function clickButton(){
const { task, tasks } = store.getState();
$.ajax({
url: './test.json',
type: 'GET',
dataType: 'text',
data: "",
timeout: 5000,
})
.done(function(data){
var jsonData = JSON.parse(data);
for( var val in jsonData){
store.dispatch(addTask(jsonData[val]));
}
})
.fail(function() {
// 通信失敗時の処理を記述
store.dispatch(addTask("fail."));
});
}
function renderApp(store){
render(
<TodoApp store={store} />,
document.getElementById('root')
);
}
store.subscribe(() => renderApp(store));
renderApp(store);
registerServiceWorker();
package.json
{
"name": "Test",
"version": "0.1.0",
"private": true,
"dependencies": {
"jquery": "^3.3.1",
"material-ui": "^1.0.0-beta.30",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1",
"redux": "^3.7.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
ファイルを作って格納しておいて
npm start
↑で作ったのをファイルで分割してみます。
最終的なファイル構成的にはこのようにする
│ index.css
│ index.js
│ logo.svg
│ registerServiceWorker.js
├─actions
│ tasks.js
├─components
│ TodoApp.js
│
├─containers
│ TodoApp.js
├─reducers
│ tasks.js
actions/tasks.js
export const addTask = (tasks) => ({
type:'ADD_TASK',
payload:{
tasks,
}
});
containers/TodoApp.js
import {connect} from 'react-redux'
import TodoApp from '../components/TodoApp.js';
import {addTask} from '../actions/tasks.js';
function mapStateToProps({task, tasks}){
return {
tasks,
};
}
function mapDispatchToProps(dispatch){
return {
addTask(tasks){
dispatch(addTask(tasks));
}
};
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp);
components/TodoApp.js
import React from 'react';
import $ from 'jquery';
// import Reboot from 'material-ui/Reboot';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import Typography from 'material-ui/Typography';
import Button from 'material-ui/Button';
import Checkbox from 'material-ui/Checkbox';
import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table';
function clickButton(addTask){
$.ajax({
url: './test.json',
type: 'GET',
dataType: 'text',
data: "",
timeout: 5000,
})
.done(function(data){
var jsonData = JSON.parse(data);
for( var val in jsonData){
addTask(jsonData[val]);
}
})
.fail(function() {
// 通信失敗時の処理を記述
addTask("fail.");
});
}
export default function TodoApp({ tasks,inputTask,addTask }){
return (
<div>
<AppBar position="static">
<Toolbar style={{backgroundColor: '#ffd699',}}>
<Typography type="title" color="inherit" style={{color:"white"}}>
Sample
</Typography>
</Toolbar>
</AppBar>
<div style={{padding:'16px'}} />
<Button variant="raised" color="primary" type="button" onClick={() => clickButton(addTask)}>実行</Button>
<Table>
<TableHead>
<TableRow>
<TableCell>#</TableCell>
<TableCell numeric>No.</TableCell>
<TableCell numeric>menu</TableCell>
</TableRow>
</TableHead>
<TableBody>
{
tasks.map(function(item,i){
return (
<TableRow key={i}>
<TableCell style={{width:'48px'}}>
<Checkbox/>
</TableCell>
<TableCell>{i}</TableCell>
<TableCell numeric>{`${item}`}</TableCell>
</TableRow>
);
})
}
</TableBody>
</Table>
</div>
);
}
reducers/tasks.js
const initialState = {
tasks: []
};
export default function tasksReducer(state = initialState, action){
switch(action.type){
case 'ADD_TASK':
return{
...state,
tasks: state.tasks.concat([action.payload.tasks])
};
default:
return state;
}
}
index.js
import React from 'react';
import {Provider} from 'react-redux';
import { createStore } from 'redux';
import {render} from 'react-dom';
import tasksReducer from './reducers/tasks.js';
import TodoApp from './containers/TodoApp.js';
import registerServiceWorker from './registerServiceWorker';
const store = createStore(tasksReducer);
function renderApp(store){
render(
<Provider store={store}>
<TodoApp />
</Provider>,
document.getElementById('root')
);
}
renderApp(store);
registerServiceWorker();
package.json
{
"name": "test",
"version": "0.1.0",
"private": true,
"dependencies": {
"jquery": "^3.3.1",
"material-ui": "^1.0.0-beta.30",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.7",
"react-scripts": "1.1.1",
"redux": "^3.7.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}