diff --git a/README.md b/README.md index 2291386..8a938d1 100644 --- a/README.md +++ b/README.md @@ -1,176 +1,3 @@ -# Pixyll +# ReactJSNews -[pixyll.com](http://www.pixyll.com) - -![Pixyll screenshot](https://cloud.githubusercontent.com/assets/1424573/3847467/134aa236-1e66-11e4-8421-4e8c122118dc.png) - -Pixyll is a simple, beautiful theme for Jekyll that emphasizes content rather than aesthetic fluff. It's mobile _first_, fluidly responsive, and delightfully lightweight. - -It's pretty minimal, but leverages large type and drastic contrast to make a statement, on all devices. - -This Jekyll theme was crafted with <3 by [John Otander](http://johnotander.com) -([@4lpine](https://twitter.com/4lpine)). - -中文版 . - -## Getting Started - -If you're completely new to Jekyll, I recommend checking out the documentation at or there's a tutorial by [Smashing Magazine](http://www.smashingmagazine.com/2014/08/01/build-blog-jekyll-github-pages/). - -### Installing Jekyll - -If you don't have Jekyll already installed, you will need to go ahead and do that. - -``` -$ gem install jekyll -``` - -#### Verify your Jekyll version - -It's important to also check your version of Jekyll since this project uses Native Sass which -is [only supported by 2.0+](http://jekyllrb.com/news/2014/05/06/jekyll-turns-2-0-0/). - -``` -$ jekyll -v -# This should be jekyll 2.0.0 or later -``` - -### Fork, then clone - -Fork the repo, and then clone it so you've got the code locally. - -### Modify the _config.yml - -The `_config.yml` located in the root of the Pixyll directory contains all of the configuration details -for the Jekyll site. The defaults are: - -```yml -# Site settings -title: Pixyll -email: your_email@example.com -author: John Otander -description: "A simple, beautiful theme for Jekyll that emphasizes content rather than aesthetic fluff." -baseurl: "" -url: "http://pixyll.com" - -# Build settings -markdown: kramdown -permalink: pretty -paginate: 3 -``` - -### Jekyll Serve - -Then, start the Jekyll Server. I always like to give the `--watch` option so it updates the generated HTML when I make changes. - -``` -$ jekyll serve --watch -``` - -Now you can navigate to `localhost:4000` in your browser to see the site. - -### Using Github Pages - -You can host your Jekyll site for free with Github Pages. [Click here](https://pages.github.com/) for more information. - -#### A configuration tweak if you're using a gh-pages sub-folder - -In addition to your github-username.github.io repo that maps to the root url, you can serve up sites by using a gh-pages branch for other repos so they're available at github-username.github.io/repo-name. - -This will require you to modify the `_config.yml` like so: - -```yml -# Site settings -title: Repo Name -email: your_email@example.com -author: John Otander -description: "Repo description" -baseurl: "/repo-name" -url: "http://github-username.github.io" - -# Build settings -markdown: kramdown -permalink: pretty -paginate: 3 -``` - -This will ensure that the the correct relative path is constructed for your assets and posts. Also, in order to run the project locally, you will need to specify the blank string for the baseurl: `$ jekyll serve --baseurl ''`. - -##### If you don't want the header to link back to the root url - -You will also need to tweak the header include `/{{ site.baseurl }}`: - -```html - -``` - -A relevant Jekyll Github Issue: - -### Contact Form - -If you'd like to keep the contact form, which uses , you will need to update the email address. - -Currently, the `contact.md` has the following: - -```html -
-``` - -Where it says `johnotander@icloud.com`, you will need to change that to the email that you wish to have the form data sent to. It will require you to fill the form out when you push it live for the first time so that you can confirm your email. - -### Page Animation - -If you would like to add a [fade-in-down effect](http://daneden.github.io/animate.css/), you can add `animated: true` to your `_config.yml`. - -### Put in a Pixyll Plug - -If you want to give credit to the Pixyll theme with a link to or my personal website somewhere, that'd be awesome. No worries if you don't. - -### Enjoy - -I hope you enjoy using Pixyll. If you encounter any issues, please feel free to let me know by creating an [issue](https://github.com/johnotander/pixyll/issues). I'd love to help. - -## Upgrading Pixyll - -Pixyll is always being improved by its users, so sometimes one may need to upgrade. - -#### Ensure there's an upstream remote - -If `git remote -v` doesn't have an upstream listed, you can do the following to add it: - -``` -git remote add upstream https://github.com/johnotander/pixyll.git -``` - -#### Pull in the latest changes - -``` -git pull upstream master -``` - -There may be merge conflicts, so be sure to fix the files that git lists if they occur. That's it! - -## Contributing - -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request - -## Thanks to the following: - -* [BASSCSS](http://basscss.com) -* [Jekyll](http://jekyllrb.com) -* [Refills](http://refills.bourbon.io/) -* [Solarized](http://ethanschoonover.com/solarized) -* [Animate.css](http://daneden.github.io/animate.css/) +Open for contributions! Create a PR with a link to your blog post, or include the text in the PR itself. diff --git a/_config.yml b/_config.yml index a00ce8c..0522b73 100644 --- a/_config.yml +++ b/_config.yml @@ -45,7 +45,7 @@ share_stumbleupon: false share_hackernews: false # Build settings -markdown: redcarpet +markdown: kramdown redcarpet: extensions: ['smart', 'tables', 'with_toc_data'] permalink: :title diff --git a/_includes/head.html b/_includes/head.html index 436eb6a..cd84eb3 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -44,7 +44,7 @@ - + + + + diff --git a/_posts/2015-07-29-modals-in-react.md b/_posts/2015-07-29-modals-in-react.md index e609e59..5239933 100644 --- a/_posts/2015-07-29-modals-in-react.md +++ b/_posts/2015-07-29-modals-in-react.md @@ -15,7 +15,7 @@ I'll be going over a few community-built components that help you create modals. There's been a few times I've needed a modal in the app I'm building. Thankfully the community has made a few really good components for this. Let's jump right in to the first: -###Elemental UI's modal +### Elemental UI's modal You can check out a demo of it right [here](http://elemental-ui.com/modal). The markup is straight forward: @@ -39,7 +39,7 @@ You can check out a demo of it right [here](http://elemental-ui.com/modal). The You can place things in the header or footer just as easily as the body which is nice. I also like the look of it, and Elemental UI as a whole. My biggest gripe about this modal component is that on scrolling the page it disappears. -###React Bootstrap +### React Bootstrap This is probably one that everyone has heard of, as it is one of the oldest React projects. You can find documentation [here](http://react-bootstrap.github.io/components.html#modals). It consists of a couple sub components for the header and footer as well. The root `modal` component expects two props, a boolean called `show`, and a function to be called `onHide`. @@ -66,7 +66,7 @@ close(){ } ~~~ -###Rackt's Modal +### Rackt's Modal Rackt's modal is much simpler than the other two, as seen on the [github page](https://github.com/rackt/react-modal). @@ -100,7 +100,7 @@ Those are the top three modal components out there. At my work, we use popovers The props are very self explanatory, except for toggleButton. It expects a component or some jsx to be passed into it. -###Boron Modal +### Boron Modal [Boron](http://madscript.com/boron/) comes out of the box with some animations. @@ -163,7 +163,7 @@ class Button extends React.Component { Thanks for checking out the post, don't forget to follow [@ReactJSNews](http://twitter.com/reactjsnews) for more content! Leave a comment if you have any suggestions. As always, you're welcome to modify this post (or write your own!) by sending in a pull request on [github](http://github.com/legitcode/reactjsnews)! -###Simple React Modal +### Simple React Modal After writing this post, I realized many of these modals have limitations and force things on you. In my case, most forced some css rules that I could not override. For this reason, I [made my own](https://github.com/zackify/simple-react-modal). You can view a demo [here](http://zach.codes/simple-react-modal/) with the default styling. diff --git a/_posts/2016-09-28-routing-in-react-native-with-jake-murzy.md b/_posts/2016-09-28-routing-in-react-native-with-jake-murzy.md index bcc40a0..1d6ebc4 100644 --- a/_posts/2016-09-28-routing-in-react-native-with-jake-murzy.md +++ b/_posts/2016-09-28-routing-in-react-native-with-jake-murzy.md @@ -12,6 +12,8 @@ Jake Murzy has been hard at work creating a new navigational library for React N +Jake Murzy has been hard at work creating a new navigational library for React Native over the last couple of months. While React JS has the benefit of the highly-regarded React Router, such a comprehensive routing solution doesn’t exist yet in the React Native community. In fact, React Native’s routing landscape has been in constant upheaval for the last year. The library itself has official three ‘navigators’ for handling decision making on which components to show the user, including ‘NavigatorIOS’, ‘Navigator’, and - more recently - ‘NavigatorExperimental’. The open source community likewise has the packages ‘React Native Router Flux’, ‘React Native Router Native’, and ‘React Native Redux Router’, which of which are in various states of completion, or, more commonly, disrepair. + [React Router Native](https://github.com/jmurzy/react-router-native) appears to focus on matching the API of the immensely popular React Router package, even going as far as introducing the concept of a URL into React Native, which bucks the notion that only web applications need or deserve a URL. --- diff --git a/_posts/2016-11-22-react-native-exponent-with-charlie-cheever.md b/_posts/2016-11-22-react-native-exponent-with-charlie-cheever.md new file mode 100644 index 0000000..5a817e1 --- /dev/null +++ b/_posts/2016-11-22-react-native-exponent-with-charlie-cheever.md @@ -0,0 +1,125 @@ +--- +layout: post +title: " Native's Exponent with Charlie Cheever" +date: 2016-11-22 17:00 +excerpt_separator: +author: Stephen Grider +published: true +categories: react, react-native +--- + +React Native continues on a development spree in late 2016. With an ambitious two-week release cycle, the framework makes rapid progress towards feature and performance parity with its native Android and iOS equivalents. At the same time, these quick release periods frequently introduce breaking changes, difficulty with setup, and challenges with basic configuration. + + +Enter Exponent, a tool that promises easier setup, development, and deployment of React Native applications. Rather than being a replacement for React Native, as it is sometimes confused, Exponent augments React Native by dramatically simplifying the development and deployment processes. Whereas basic setup with an Android environment to develop with React Native can take over an hour by hand, even for experienced engineers, Exponent shortens the time to start to “Hello World” to a handful of minutes. + + + +React Native continues on a development spree in late 2016. With an ambitious two-week release cycle, the framework makes rapid progress towards feature and performance parity with its native Android and iOS equivalents. At the same time, these quick release periods frequently introduce breaking changes, difficulty with setup, and challenges with basic configuration. + +Enter Exponent, a tool that promises easier setup, development, and deployment of React Native applications. Rather than being a replacement for React Native, as it is sometimes confused, Exponent augments React Native by dramatically simplifying the development and deployment processes. Whereas basic setup with an Android environment to develop with React Native can take over an hour by hand, even for experienced engineers, Exponent shortens the time to start to “Hello World” to a handful of minutes. + +[Exponent’s](https://getexponent.com/) prime feature is revealed as it’s namesake IDE. The Exponent IDE is development platform for not only developing apps to test in their respective environment simulators, but also simplifies testing them on real devices. + + +One of the cofounders of Exponent, [Charlie Cheever](https://twitter.com/ccheever), agreed to answer a few questions about Exponent and its purpose in the community. + +--- + +**Hi, Charlie. Congrats on the release of Exponent! One of the toughest aspects of Exponent is understanding what its purpose is. What is the primary goal of Exponent?** + + +Thanks :) + + +Before I worked on mobile software, I spent about 15 years making websites. When I started working on the Quora iPhone app and Android app, it felt like time traveling back to 1993. So many things to worry about that have nothing to do with the product you want to build. + + +One thing we’re trying to do with Exponent is making it as easy to develop native mobile apps as it is to make websites, or even easier! I think about how I learned to build software as a kid--making games on my TI-85 and making Hypercard stacks--and I want to make it so that the middle school kids of today can make cool stuff for themselves and their friends. + +**Basic environment setup of the iOS and Android simulators for developing React Native apps is commonly cited as a headache by new developers. What does Exponent do to alleviate this pain?** + + +The biggest thing that Exponent does is take care of everything related to native code for you. So you don’t need to know Swift/Obj-C/Java or even have Xcode or Android Studio to be able to write React Native apps. You write just JavaScript and Exponent has everything else already setup for you. + + +Since you don’t write any native code with Exponent, just JavaScript, Exponent has a lot of the most popular native modules built in. Native maps, push notifications, Facebook and Google login, camera and camera roll access, contacts, TouchID, and a native video player are all included among other things. We’re always adding more of these as well. We just added full OpenGL support last week and did a game jam and made some mini games with it and are adding sound soon. + + +We sometimes talk about Exponent as being like Rails for React Native. You could write a website in Ruby on your own. but Rails sets up a bunch of sensible things right off that bat that work together in a coherent way and we kind of do the same thing for React Native. Exponent includes instant app updating as a default, so you can deploy new code and assets with one command in seconds, even faster than most websites can be deployed. + + +**Even after getting set up with the Android and iOS simulators, testing a React Native app on a real phone can still be a challenge. How does Exponent make it easier to share apps in progress with would-be users?** + + +You can actually open any Exponent project that you’re working on in our development app right away. When you develop with Exponent, you get a URL for your project, and you can open that URL on any phone with the Exponent developer app which you can download from the iOS App Store or Google Play Store. You don’t need to jack your phone into your computer--just open the URL. + + +Another really cool thing about this is that, if you’re working with someone else, you can just send them the URL and they can open it on their phone as well, even if they are halfway around the world. + + +We’ve done a bunch of work to make this pretty nice, like having `console.log` work even if the phone running your code isn’t plugged into your computer. And you can, of course, open your project on the iOS Simulator or an Android Emulator as well if you prefer. + + +I know you mentioned a lot of people have trouble getting React Native setup on Android especially. With Exponent, every project works on both iOS and Android from the start and you never have to deal with Android Studio, so the process of getting going is much easier. + + +**What type, or genre, of application would be a good fit with React Native and Exponent?** + + +I would actually use React Native for almost any mobile app at this point. Doing development the traditional way (writing Swift/Java/Obj-C code) is just too hard to iterate on when you consider the slowness of the code-compile-copy-run loop and the fact that you have to write your app twice (and then keep it in sync!). The other thing that is an absolutely huge deal here but is sometimes overlooked is the layout engine. It’s much easier to build and change a layout in React Native’s Flexbox than any of the UI libraries that I’ve seen for Java/Swift/Obj-C. + + +And if you need to do something really intense, like Snapchat live video filters, you can just write your own code as a native module and write the rest of your app in JS. + + +I would use Exponent for anything I could because it just saves a lot of time and headaches since you don’t need to deal with Android Studio or Xcode. Some people don’t know that you can turn an Exponent project into an app store app for iOS or for Android with just one command. + + +In general, Exponent will work for you in pretty much every case where just having a mobile website is one of the things that you’re considering. The features are pretty equivalent except that Exponent apps feel like native apps and mobile apps still feel like mobile web apps. + + +The main reason *not* to use Exponent is if you have some custom native code that you need that isn’t included with Exponent. The most common reasons that people can’t use Exponent are if they need use Bluetooth or HealthKit or something else low level that isn’t built in to Exponent; or if they need to integrate into an existing project (though we are working right now on a solution that will let you do this). + + +The exception to all this is games. If you are making a mobile game, Unity is probably the best choice for you. But we did add OpenGL support to Exponent recently and had a game jam and I was surprised at how good some of the entries were, so I think that might change. + + +TL;DR: For apps that aren’t games, always use React Native (if you need to do something super custom, just do it as a native module). If you can, use Exponent (you can most of the time but check our docs to make sure we’re not missing anything you need). + + + +**One aspect of React Native that seems to be undergoing constant flux is its solution for navigation. Between the built in Navigators and open source solutions, do you have any thoughts on an ideal solution for navigation?** + + +Short version: I think you should use Ex-Navigation that Adam Miskiewicz (skevy) and Brent Vatne on our team wrote. Skevy in particular has been thinking about navigation in mobile apps and React Native for a long time. Using Ex-Navigation is definitely a better idea than Navigator or NavigatorIOS. + + +To make things confusing, there is also NavigatorExperimental (yes, that’s different from Ex-Navigation) and ExNavigator (which was made by James Ide and Ex-Navigation is based on). The good news is that everyone working on these problems got together and decided to merge them all together. I don’t know how long that is going to take but it will probably be released sometime in the next few months under the name React Navigation, and that should unify everyone’s efforts! + + +There is also this other school of thought where some people like to use the platform-specific native code for navigation which is the approach that the Wix Navigator uses. I have a strong personal view that its preferable to write UI components like this in JS because I actually think you want your app to be the same across iOS and Android (they are both just black rectangles with touch screens!) and JS tends to make your code more composable and customizable. + + +Use Ex-Navigation and keep an eye out for React Navigation! Use JS instead of native for this UI code! + + +**Given the increasingly fast development and deployment times, handling API setup for dealing with data is becoming a large obstacle to React Native apps. Do you have any thoughts about the use of Backend-As-A-Service solutions like Firebase compared to rolling your own API with Node/Express, Rails, or similar?** + + +I don’t have a strongly held view on this right now. There are so many solutions that fit the use cases of people with different needs. We’re seeing things getting easier and easier in every direction that you look. + + +If you want to write your own code and you’re using JS, you can use something like Zeit’s new `now` stuff to deploy essentially instantly. If you want a more general purpose solution, Heroku is also really easy. And then of course there is AWS and Google Cloud, etc. + + +It’s trivially easy for React Native apps to communicate with essentially any backend that uses HTTP/JSON since `fetch` and `JSON.parse` are built-in. + + +If you don’t want to write any code, it seems like Firebase has become the most popular solution since Parse announced its shutdown. One nice thing about Firebase is that you can use their hosted database stuff with React Native using just JS, which means it works just fine with Exponent. Someone wrote up a guide to how to do this here: [https://gist.github.com/sushiisumii/d2fd4ae45498592810390b3e05313e5c](https://gist.github.com/sushiisumii/d2fd4ae45498592810390b3e05313e5c) + + +Longer term, it seems like something like GraphQL/Relay should become really popular, but that stuff is too hard to setup and use still to be mainstream just yet. I’m not sure whether it will be GraphQL/Relay maturing and getting revised that wins or something else that is slightly different and easy to think about as a developer that comes and beats it, but directionally, it’s definitely right. We built something like this at Quora and it saved a ton of development time. + + +I would just use whatever you are most comfortable with -- almost anything will work! React Native is really similar to the the web in terms of its client capabilities and so I would just think about a React Native or Exponent app as being mostly like a website. diff --git a/_posts/2017-01-17-react-js-with-cloudinary.md b/_posts/2017-01-17-react-js-with-cloudinary.md new file mode 100644 index 0000000..c50a0f1 --- /dev/null +++ b/_posts/2017-01-17-react-js-with-cloudinary.md @@ -0,0 +1,322 @@ +--- +layout: post +title: "Leveraging React for Easy Image Management" +date: 2017-01-17 17:00 +excerpt_separator: +author: Stephn Grider +published: true +categories: react, cloudinary, react native +--- + +[React](https://facebook.github.io/react/) is a good tool when it comes to building flexible and reusable UI components. However, it's "one of those libraries" that cannot handle all the tasks involved in building a full fleshed UI project. Other supporting tools - such as a recently announced [React SDK](https://github.com/cloudinary/cloudinary-react) from [Cloudinary](http://cloudinary.com/?utm_source=Scotch&utm_medium=Sponsored_Post_6&utm_content=React_Gallery) - are available to provide solutions that the React core cannot. + + + +In such cases where media (images and videos) becomes a heavy task to handle, [Cloudinary](http://cloudinary.com/?utm_source=Scotch&utm_medium=Sponsored_Post_6&utm_content=React_Gallery) simplifies the process with the new React SDK. Let's build and image library with Cloudinary and React using the [Cloudinary's React SDK](https://github.com/cloudinary/cloudinary-react). + +## Prerequisites + +The only requirements for using [Cloudinary](http://cloudinary.com/?utm_source=Scotch&utm_medium=Sponsored_Post_6&utm_content=React_Gallery) in your existing React project are to install the React SDK and the upload widget. If you do not have an existing React project and want to try these examples, take the following steps: + +### 1. Install Dependencies +We need a minimal amount of dependencies so we can focus on building a media library and not structuring a React app: + +```json +{ + "name": "img-library", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "watch": "webpack -d --watch", + "build": "webpack", + "serve": "serve ./public" + }, + "author": "", + "license": "MIT", + "devDependencies": { + "babel-core": "^6.18.2", + "babel-loader": "^6.2.9", + "babel-preset-es2015": "^6.18.0", + "babel-preset-react": "^6.16.0", + "serve": "^1.4.0", + "webpack": "^1.14.0" + }, + "dependencies": { + "axios": "^0.15.3", + "cloudinary-react": "^1.0.1", + "react": "^15.4.1", + "react-dom": "^15.4.1" + } +} +``` + +React (and React DOM) must be used since we are making a React app. The `cloudinary-react` dependency is Cloudinary's React SDK, which we will soon see how it works. `axios` is a tool for making HTTP requests and, in our case, we will use it request images from the Cloudinary server. + +```bash +# Install dependencies +npm install +``` + +### 2. Setup Webpack +Webpack is our build tool. Only minimal settings are required to have a build running and our React app compiling: + +```js +// ./webpack.config.js +var webpack = require('webpack'); +var path = require('path'); + +var BUILD_DIR = path.resolve(__dirname, 'public'); +var APP_DIR = path.resolve(__dirname, 'src'); + +var config = { + entry: APP_DIR + '/index.jsx', + output: { + path: BUILD_DIR, + filename: 'bundle.js' + }, + module : { + loaders : [ + { + test : /\.jsx?/, + include : APP_DIR, + loader : 'babel' + } + ] + } +}; + +module.exports = config; +``` + +Basic configuration - an entry, output and loaders to handle the React `.jsx` files. + +### 3. Entry Points +We need to create an entry point, as we specified in the Webpack configuration, and another entry point for the browser, which is an `index.html` file: + +```js +// ./src/index.jsx +import React, { Component } from 'react'; +import { render } from 'react-dom'; + +class Main extends Component { + render() { + return ( +
+

Scotchage

+
+ ); + } +} + +render(
, document.getElementById('container')); +``` + +```html + + + + + + + + + +
+ + + + +``` + +### 4. Create Cloudinary Account +You need a Cloudinary account to continue with these examples. Sign up for free and store your credentials safely as shown on the dashboard: + +![](http://imgur.com/HdBYCWr.jpg) + +## Uploading Images +Before using the React SDK to deliver images from the Cloudinary servers, let's use the awesome Cloudinary upload widget to upload images. First, we need to add this widget to our `index.html`: + +```html + + + + . . . + + + . . . + + + + + +``` + +Next, we create a button, attach an event to it and upload an image once the button is clicked: + +```js +import React, { Component } from 'react'; +import { render } from 'react-dom'; + +class Main extends Component { + + uploadWidget() { + cloudinary.openUploadWidget({ cloud_name: 'CLOUD_NAME', upload_preset: 'PRESET', tags:['xmas']}, + function(error, result) { + console.log(result); + }); + } + render(){ + return ( +
+

Galleria

+
+ +
+
+ + ); + } +} + +render(
, document.getElementById('container')); +``` + +The `uploadWidget` member method is the handler invoked by the click event to handle our image upload by calling `cloudinary.openUploadWidget`. `openUploadWidget` takes a config object and the upload callback handler. The config object must have at least `cloud_name` and `upload_preset` properties with valid values. You can read more about Cloud Names and Upload Presets. + +![](http://imgur.com/KeMwAtv.jpg) + +## Delivering Images with SDK + +The Cloudinary React SDK has three major components, __`Image`__, __`CloudinaryContext`__ and __`Transformation`__: + +- __Image__: This component is responsible for the actual delivery of images. It takes the image ID and asks the server for this image. When the image is provided, it is also responsible for painting the image on the browser. +- __Transformation__: This component is used to apply transformations to images delivered with `Image`. +- __CloudinaryContext__: You can specify Cloudinary configuration for each image on the `Image` component. This can be tedious when you are dealing with multiple images. `CloudinaryContext` allows you to apply configuration to a group of `Image`s. + +Most times you would end up with a structure like this: + +```html + + + + + + + + + +``` + +Back to our demo app, we can request an image from the Cloudinary server and display it with the following components: + +```js +import React, { Component } from 'react'; +import axios from 'axios'; +import { CloudinaryContext, Transformation, Image } from 'cloudinary-react'; +import { render } from 'react-dom'; + +class Main extends Component { + constructor(props) { + super(props); + this.state = { + gallery: [] + } + } + componentDidMount() { + // Request for images tagged xmas +axios.get('http://res.cloudinary.com/christekh/image/list/xmas.json') + .then(res => { + console.log(res.data.resources); + this.setState({gallery: res.data.resources}); + }); + } + uploadWidget() { + // . . . + } + render(){ + return ( +
+

Galleria

+
+ + { + this.state.gallery.map(data => { + return ( +
+
+ + + + + +
Created at {data.created_at}
+
+
+ ) + }) + } +
+
+
+
+ + ); + } +} + +render(
, document.getElementById('container')); +``` + +Take one more look at the upload code: + +```js + cloudinary.openUploadWidget({ cloud_name: 'christekh', upload_preset: 'idcidr0h', tags:['xmas']}, + function(error, result) { + . . . +``` + +Each image is tagged with `xmas`, which serves as a way to request images with this tag as a collection. This is exactly what we are using the `axios` library to do when the component mounts: + +```js +axios.get('http://res.cloudinary.com/CLOUDNAME/image/list/xmas.json') + .then(res => { + console.log(res.data.resources); + this.setState({gallery: res.data.resources}); + }); +``` + +`axios` uses promises, so whenever the promise resolves in our case, we have a payload of images. We take advantage of React state to update our UI with the fetched resources. + +Down to rendering, we configure the `CloudinaryContext` with our `cloud_name`, iterate over the `gallery` state that stores the images and displays them using the `Image` component. We also apply few transformations using the `Transformation` component. + +> For security reasons, Cloudinary will not allow you to make such request from the client unless you tell it to. The best way to go is to use the admin API via a backend SDK and then send the resource list to the client. + +![](http://imgur.com/uCKacWp.jpg) + +## Updating State with New Uploads +We are able to upload images and request for images to be displayed on the user's browsers. Here is how we update the displayed images instantly when the user uploads a new image: + +```js +uploadWidget() { + let _this = this; + cloudinary.openUploadWidget({ cloud_name: 'CLOUDNAME', upload_preset: 'PRESET', tags:['xmas']}, + function(error, result) { + // Update gallery state with newly uploaded image + _this.setState({gallery: _this.state.gallery.concat(result)}) + }); + } +``` + +Rather than logging the uploaded image information to the console, we update the `gallery` state, which bears the list of requested images, by concatenating the uploaded result to the `gallery`. + +## Image Management Simplified +Image uploads, transformation and delivery has never been easier. These tasks have been a serious challenge for developers. Cloudinary has created a way to abstract all this hard work, enabling you to simply plug and play. diff --git a/_posts/2017-03-06-the-diverse-react-navigation-ecosystem.md b/_posts/2017-03-06-the-diverse-react-navigation-ecosystem.md new file mode 100644 index 0000000..930d134 --- /dev/null +++ b/_posts/2017-03-06-the-diverse-react-navigation-ecosystem.md @@ -0,0 +1,34 @@ +--- +layout: post +title: "The Diverse React Navigation Ecosystem" +date: 2017-03-06 17:00 +excerpt_separator: +author: Stephen Grider +published: true +categories: react, react native +--- + +The routing ecosystem around React and React Native is quite different. One is characterized by a strong incumbent, and the other is plagued by rapid change. + + + + +### React JS + +No question about it, React Router ([ReactTraining/react-router](https://github.com/ReactTraining/react-router)) is king here. They have the benefit of several years of active development, along with an active community submitting PR’s, fixes, etc. Supplement that with myriad tutorials and how-to’s and you end up with a well-supported, stable product. To be fair, React Router has suffered some major API upsets, and is nearly the poster-child for javascript fatigue but the maintainers have declared their lasting support for a few specific versions, which means you can plop down with V3 and be good to go for the next 12 to 24 months. + +### React Native + +Ok, this is where things start to get really, really crazy. The most important thing to keep in mind is that the React Native team has produced three navigation helpers: NavigatorIOS, Navigator, and NavigatorExperimental. + +* NavigatorIOS was quickly deprecated, as it was supported only by (you guessed it) IOS. +* Navigator is the currently endorsed solution for navigation, at least if you are following the official docs. However, its about to be upset by- +* NavigationExperimental. This is an updated navigator that has learned some lessons from Navigator, and has some solid integration with Redux. ‘Navigator’ is (or was!) sleighted to be deprecated in favor of NavigationExperimental at some point. + +Already you have three ‘official’ navigators supported by the React Native team. The big issue with all three of these is that they are somewhat lightweight and don’t include a lot of common navigation situations out of the box, like sidebars, tab bars, headers, etc. To solve that, the community has introduced… + +* React Native Router Flux ([aksonov/react-native-router-flux](https://github.com/aksonov/react-native-router-flux)). My personal favorite, this is router is based upon NavigationExperimental. You can imagine that the authors looked at NavigationExperimental, realized that everyone would be writing the same wrapper code around it, and so created this project. +* React Native Router (t4t5/react-native-router). Haven’t used it, but it is colossally popular. +* React Router Native ([jmurzy/react-router-native](https://github.com/jmurzy/react-router-native)). Strives for API conformity with React Router (the above mentioned one). The great approach here is that they bring in the concept of a URL in native apps, where one doesn’t otherwise exist. This is a great approach that simplifies a lot of common routing situations. +Of course, there’s one more big solution that is supposedly going to become the standard: +* React Navigation ([react-community/react-navigation](https://github.com/react-community/react-navigation)). Seen as a solution that will soon be ‘official’ in the community, it is intended to replaced NavigationExperimental. This package is still in active development, so I expect at least a bit of API upset over the coming months. If you want to use official solutions, go with this, if you want a tried and true solution, go with React Native Router Flux. diff --git a/_posts/2017-03-07-component-kits-for-react-native.md b/_posts/2017-03-07-component-kits-for-react-native.md new file mode 100644 index 0000000..0a15d80 --- /dev/null +++ b/_posts/2017-03-07-component-kits-for-react-native.md @@ -0,0 +1,56 @@ +--- +layout: post +title: "Component Kits for React Native" +date: 2017-03-07 17:00 +excerpt_separator: +author: Stephen Grider +published: true +categories: react, react native +--- + +You won’t find as many styling solutions for React Native as you will for React JS. This stems from two simple realities: + +1. React Native is a much smaller target for component libraries than traditional CSS frameworks. In other words, Bootstrap CSS can be used with any web framework, whereas component libraries for React Native only work with…you guessed it…React Native. +2. Customizing React Native styling isn’t the easiest thing in the world. Many apps demand custom styling, which makes component kits not too useful. In addition, it is challenging to customize each and every component, as the flexibility that you gain with traditional CSS on the web doesn’t carry over easily to component libraries. + +With that said, here are a few options. + + + + +You won’t find as many styling solutions for React Native as you will for React JS. This stems from two simple realities: + +1. React Native is a much smaller target for component libraries than traditional CSS frameworks. In other words, Bootstrap CSS can be used with any web framework, whereas component libraries for React Native only work with…you guessed it…React Native. +2. Customizing React Native styling isn’t the easiest thing in the world. Many apps demand custom styling, which makes component kits not too useful. In addition, it is challenging to customize each and every component, as the flexibility that you gain with traditional CSS on the web doesn’t carry over easily to component libraries. + +With that said, here are a few options. + +### NativeBase - [Essential cross-platform UI components for React Native](http://nativebase.io/) + +A huge collection of components, most of which look quite nice. That’s the plus side. The down side is that some of the components are somewhat buggy. No offense to the library authors, its just the state of the library - it needs a bit of work. For example, here’s an issue I opened a few days ago when I discovered the swipe deck component crashed when only a single data element was provided: [DeskSwiper throws on single element lists · Issue #562 · GeekyAnts/NativeBase](https://github.com/GeekyAnts/NativeBase/issues/562). The authors fixed it up awfully fast, but, hey, that’s a bug that seems like it could have been caught earlier. + +--- + +### React Native Elements - [react-native-community/react-native-elements](https://github.com/react-native-community/react-native-elements) + + +This is my personal favorite. The styling is generally platform agnostic; it won’t look out of place using it on either Android or iOS. Each component has simple customization, the docs are solid, and it comes with a good set of icons. This is a no-brainer. + +--- + +### React Native Material Design - [react-native-material-design/react-native-material-design](https://github.com/react-native-material-design/react-native-material-design) + + +Another solid choice, but mostly only useful for Android. Again, its a bit unsettling to see material design - traditionally a stable of Android devices - on iOS. Besides that, the docs are still a work in progress, as evidenced by the lack of docs for nearly half of the components. Nonetheless, if you’re looking for a material design solution, this is better than nothing. It is also worth noting that the project looks generally unmaintained. + +--- + +### React Native Material Kit - [xinthink/react-native-material-kit](https://github.com/xinthink/react-native-material-kit) + +Another material design solution, but much better maintained than React Native Material Design. This one has the added benefit of a nicer customization API for creating your own custom components - see the docs on this. It also has some more dynamic components like progress bars and sliders, which you may not see on other frameworks. Anything that helps save you time to build your app is always a solid benefit. + +--- + +### Do Your Own Styling! + +If none of these choices float your boat, you can always learn how to style components from scratch yourself. I have a course on Udemy that will teach you how to make perfectly reusable components for your own projects. Check it out here: [The Complete React Native and Redux Course - Udemy](https://www.udemy.com/the-complete-react-native-and-redux-course/?couponCode=4IJ2N25F) diff --git a/_posts/2017-03-28-proxies-with-redux-types.md b/_posts/2017-03-28-proxies-with-redux-types.md new file mode 100644 index 0000000..f0fd728 --- /dev/null +++ b/_posts/2017-03-28-proxies-with-redux-types.md @@ -0,0 +1,133 @@ +--- +layout: post +title: "Using Proxies with Redux Types" +date: 2017-03-28 16:00 +excerpt_separator: +author: Alec Barlow +published: true +categories: react, redux, ES6, ES2015 +--- + +One of the most common problems that I run into when using Redux is trying to figure out why an action is not being captured by a reducer. For someone just getting starting with Redux, debugging this issue can be especially overwhelming because of how Redux manages data flow. So before you start pouring over configuration code, or the logic contained in your action creators and reducers, please, make sure your action types are defined and spelled correctly. + + + +One of the most common problems that I run into when using Redux is trying to figure out why an action is not being captured by a reducer. For someone just getting starting with Redux, debugging this issue can be especially overwhelming because of how Redux manages data flow. So before you start pouring over configuration code, or the logic contained in your action creators and reducers, please, make sure your action types are defined and spelled correctly. + +In any application that I have built, most bugs that I have run into are simply due to typos. However, the solution to this particular problem is harder to spot because no errors are raised when the application is run. Take a look at the snippet below. + +```js +// actionTypes.js + +export const FETCH_FILE_REQUEST = 'fetch_file_request'; +export const FETCH_FILE_SUCCESS = 'fetch_file_success'; +export const FETCH_FILE_FAIL = 'fetch_file_fail'; + + +// filesReducer.js + +import { + FETCH_FILE_REQUEST, + FETCH_FILE_SUCESS, + FETCH_FILE_FAIL +} from '../actions/actionTypes'; + +const filesReducer = (state = {}, action) => { + switch (action.type) { + case FETCH_FILE_SUCESS: + return { ...state, file: action.payload }; + default: + return state; + } +} + +export default filesReducer; +``` + +Assuming we dispatched an action with type FETCH_FILE_SUCCESS, the filesReducer should catch the action before the default case is returned. But what if that is not happening? Where do we start the debugging process. There does not appear to be anything wrong with the code in the reducer; the action type was imported and matches the case in the switch statement. There are no errors in the browser. Where is the issue? + +You may have noticed that I misspelled SUCCESS in filesReducer.js, but the reason this can be hard to catch is because importing undefined types does not cause an error, so when we import FETCH_FILE_SUCESS, its value is actually undefined, so our reducer always hits the default case. + +It would be nice if the existing import/export system could help us catch this. Unfortunately, since action types are just strings, validating their existence is challenging. Luckily, we have another option. + +#### Enter Proxies + +Proxies are a feature of ES2015 that allow us to customize operations on a object. They can be used in many different ways, and you can find some useful examples [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) and [here](https://developers.google.com/web/updates/2016/02/es2015-proxies). For our problem, this example from [Mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) looks promising: + +```js +let validator = { + set: function(obj, prop, value) { + if (prop === 'age') { + if (!Number.isInteger(value)) { + throw new TypeError('The age is not an integer'); + } + if (value > 200) { + throw new RangeError('The age seems invalid'); + } + } + + // The default behavior to store the value + obj[prop] = value; + + // Indicate success + return true; + } +}; + +let person = new Proxy({}, validator); + +person.age = 100; +console.log(person.age); // 100 +person.age = 'young'; // Throws an exception +person.age = 300; // Throws an exception +``` + +So if proxies can be used to validate that properties assigned to an object are of a certain type and value, we should definitely be able to ensure that our action types are never undefined, or else throw an error that will be easy for us to fix. Let’s refactor our actionTypes.js file. + +```js +// actionTypes.js + +const types = { + FETCH_FILE_REQUEST: 'fetch_file_request', + FETCH_FILE_SUCCESS: 'fetch_file_success', + FETCH_FILE_FAIL: 'fetch_file_fail' +} + +const typeValidator = { + get(obj, prop) { + if (obj[prop]) { + return prop; + } else { + throw new TypeError(`${prop} is not a valid action type`); + } + } +} + +module.exports = new Proxy(types, typeValidator); + +``` + +First, we define a object containing all our action types. Then we define our validator handler typeValidator. The get method inside our handler is called a trap, and provides access to the properties of a object. If the property we are looking for, an action type, in this case, exists in the types object, return that prop, unmodified. Otherwise, throw an error because the prop does not exist. + +Finally, export a new proxy, passing the types object as the target and the typeValidator as the handler. However, it is important to note that the ES2015 module system does not work well with proxies, so module.exports and require() must be used for exporting and importing the types. + +Barely any code needs to change in the reducer and action creator files, but in order for the action types to be imported successfully, we just need couple lines of code in a new file: + +```js +// actionTypesProxy.js + +export const { + FETCH_FILE_REQUEST, + FETCH_FILE_SUCCESS, + FETCH_FILE_FAIL, +} = require('./actionTypes'); + +// in the reducer and action creator files +// change '../actions/actionTypes' to +// '../actions/actionTypesProxy' + +``` + +By creating a proxy to verify the existence of an action type, we no longer have to worry about correctly naming a property upon import because an error will be thrown in the browser console as soon as the application starts. So, reduce the number headaches you get when developing an application using Redux and start using [proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). + +Interested in learning how to build applications using Redux with ReactJS. Check out this online course! [Modern React with Redux](https://www.udemy.com/react-redux/) diff --git a/index.html b/index.html index 2dd582c..002ca9c 100644 --- a/index.html +++ b/index.html @@ -16,6 +16,7 @@ {{ post.excerpt }} {% endif %}

+ Read More {% endfor %}