Twitter app ب laravel & react js الجزء الثالت
imadbelasri
Reactjs
RS
فهاد الجزء الثالت والاخير من Twitter App ب laravel & react js غادي نشوفوا كيفاش نخدموا ب react js باش نزيدو les tweets ديالنا.
ف laravel كتجي ب vue js فالإعدادات المسبقة فغادي نديرو تغيير ل react js منبعد غادي نشوفوا كيفاش نزيدو les tweets ومنبعد نعرضهم فنفس الوقت.
نظرة سريعة بالفيديو
1- إضافة react js ل app ديالنا
فكيف قلنا قبل laravel كتجي ب vue js فالإعدادات المسبقة باش نبدل من vue js ل react js كندير هاد ل commande ف cmd :
php artisan preset react
منبعد خص ندير تثبيت ل modules لي غادي نحتاج فدير هاد ل commande :
npm install
منبعد دير هاد ل commande :
npm run dev
ثم هاد ل commande :
npm run watch
فدبا تحولنا من vuejs ل reactjs فغادي تمشي ل dossier resources/js/components غادي تلقى ملف سميتو index.js يلا مكانش زيدو.
فيه كود بسيط سبق وشفنا كلشي فدورة react js كنسترجع ل component App وكنعرضوا ف div لي عندها ل id root لي غادي نزيدوها من بعد فالصفحة الرئيسية.
الكود ديال الملف index.js هو :
//
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
if (document.getElementById('root')) {
ReactDOM.render(<App />, document.getElementById('root'));
}
2- تعديل الملف App.js
دائما ف components كاين الملف App.js لي غادي ندير عليه تعديلات فتقريبا كلشي شفناه فدورة react js حتى حاجة ما جديدة.
كنزيد state لي فيها array posts و body ف posts غادي نزيد les tweets من بعد ما نسترجعهم وهاد العملية كنديرها فاش كتشارجا الصفحة الرئيسية فكنفذ ل fonction getAllPosts لي كنسترجع بها les tweets وكنزيدهم فل array posts.
ف render كنخدم بل map لي كندور بها على les tweets لي عندي وكنعرض وحدة بوحدة ثم عندي ل form لي فيها حقل واحد مرتبط مع ل body لي زدنا ف state.
فاش كنضغط على زر الإضافة كتنفذ ل fonction formSubmit لي كتنفذ ل fonction postData لي كتزيد tweet وكتعرضها مع les tweets لي عندنا.
بالنسبة ل setInterval هي فقط كتدير تحديث ل tweets لي معروضين كل 10 ثواني باش كنعرض لي تزادو جداد.
الكود ديال الملف App.js هو :
//
import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {
constructor(props){
super(props);
this.state = {
body : '',
posts : [],
loading : false
};
//bind
//we bind just functions who interact with events like form events input events & button events
this.formSubmit = this.formSubmit.bind(this);
this.inputChange = this.inputChange.bind(this);
}
//submit form data
formSubmit(e){
e.preventDefault();
this.postData();
// console.log(this.state.body);
}
//post data
postData(){
axios.post('/posts/create',{
body : this.state.body
}).then(
response => this.setState({posts : [response.data,...this.state.posts]})
);
this.setState({body : ''});
}
//getAllPosts
getAllPosts(){
this.setState({
loading : true
});
axios.get('/posts').then(
response => this.setState({posts : [...response.data.posts],loading : false})
);
}
//get value from input
inputChange(e){
this.setState({
body : e.target.value,
});
}
//load all posts when app is mounted
componentWillMount(){
this.getAllPosts();
}
//add real time posts show
componentDidMount(){
this.interval = setInterval(() => this.getAllPosts(),10000);
}
//clear interval
componentWillUnmount(){
clearInterval(this.interval);
}
render() {
return (
<div className="container">
<div className="row justify-content-center">
<div className="col-md-6">
<div className="card">
<div className="card-header">Tweets</div>
<div className="card-body">
{this.state.posts.map(post =>
<div key={post.id} className="media">
<div className="media-left">
<img src={post.user.avatar} alt="" width="60" height="60" className="media-object mr-2"/>
</div>
<div className="media-body">
<div className="user">
<p>
<a href={`/user/${post.user.username}`}><span className="font-weight-bolder">{post.user.username}</span></a>
<span>{post.created_at}</span>
</p>
</div>
{post.body}
</div>
</div>
)}
</div>
</div>
</div>
<div className="col-md-6">
<div className="card">
<div className="card-body">
<form onSubmit={this.formSubmit}>
<div className="form-group">
<textarea
value = {this.state.body}
onChange = {this.inputChange}
className="form-control"
maxLength="140"
cols="30" rows="10"
placeholder="Quoi de neuf"
required
/>
</div>
<input type="submit" value="publier" className="btn btn-block btn-outline-secondary"/>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
3- إضافة الصفحة الرئيسية
في ما يخص login système فكيكفي باش تدير هاد ل commande :
php artisan make:auth
وغادي يتزاد كلشي أتوماتيكيا
منبعد ف dossier views غادي تلقى ملف جديد تزاد سميتو home.blade.php غادي نديرو عليه تعديلات لي فيها div لي عطيناها id root ولي فيها كيتعرضوا les tweets وايضا الفورم لي كتمكن من الإضافة.
وكنعرض ايضا المتابعين ديال المستخدم الحالي والناس لي متابع المستخدم ولي فاش كيضغط على أي واحد فيهم كيتوجه لبروفيل ديالو.
الكود ديال الملف home.blade.php هو :
//
@extends('layouts.app')
@section('content')
<div class="container">
<div id="root"></div>
</div>
<hr>
<div class="container">
Abonnements
<hr>
@foreach($following as $user)
<p><a href="{{route('user.profile',$user)}}">{{$user->username}}</a></p>
@endforeach
<hr>
Abonnés
<hr>
@foreach($followers as $user)
<p><a href="{{route('user.profile',$user)}}">{{$user->username}}</a></p>
@endforeach
</div>
@endsection
4- إضافة les routes ف web.php
فآخر حاجة باش نتمكن من التنقل ما بين الصفحات ديالي لازمني ما نزيد les routes فالملف web.php.
فالكود لي غادي تزيد ف web.php هو :
//
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Auth::routes();
Route::group(['middleware' => ['auth']],function(){
Route::get('/','TimelineController@index');
Route::post('/posts/create','PostsController@create');
Route::get('/posts','PostsController@index');
Route::get('/user/{user}','UsersController@index')->name('user.profile');
Route::get('/user/{user}/follow','UsersController@follow')->name('user.follow');
Route::get('/user/{user}/unfollow','UsersController@unfollow')->name('user.unfollow');
});