diff --git a/curriculum/challenges/english/03-front-end-libraries/react-and-redux/map-dispatch-to-props.english.md b/curriculum/challenges/english/03-front-end-libraries/react-and-redux/map-dispatch-to-props.english.md
index 71b0b71573..a4c8b6bc68 100644
--- a/curriculum/challenges/english/03-front-end-libraries/react-and-redux/map-dispatch-to-props.english.md
+++ b/curriculum/challenges/english/03-front-end-libraries/react-and-redux/map-dispatch-to-props.english.md
@@ -9,7 +9,15 @@ isRequired: false
mapDispatchToProps()
function is used to provide specific action creators to your React components so they can dispatch actions against the Redux store. It's similar in structure to the mapStateToProps()
function you wrote in the last challenge. It returns an object that maps dispatch actions to property names, which become component props
. However, instead of returning a piece of state
, each property returns a function that calls dispatch
with an action creator and any relevant action data. You have access to this dispatch
because it's passed in to mapDispatchToProps()
as a parameter when you define the function, just like you passed state
to mapStateToProps()
. Behind the scenes, React Redux is using Redux's store.dispatch()
to conduct these dispatches with mapDispatchToProps()
. This is similar to how it uses store.subscribe()
for components that are mapped to state
.
For example, you have a loginUser()
action creator that takes a username
as an action payload. The object returned from mapDispatchToProps()
for this action creator would look something like:
-{
+
+```jsx
+{
+ submitLoginUser: function(username) {
+ dispatch(loginUser(username));
+ }
+}
+```
+
submitLoginUser: function(username) {
dispatch(loginUser(username));
}
}react-redux
package to help accomplish these tasks.
React Redux provides a small API with two key features: Provider
and connect
. Another challenge covers connect
. The Provider
is a wrapper component from React Redux that wraps your React app. This wrapper then allows you to access the Redux store
and dispatch
functions throughout your component tree. Provider
takes two props, the Redux store and the child components of your app. Defining the Provider
for an App component might look like this:
-<Provider store={store}>
+
+```jsx
+
<App/>
</Provider>
<div>+ +```jsx +
<p>Paragraph One</p>
<p>Paragraph Two</p>
<p>Paragraph Three</p>
</div>
Paragraph One
+Paragraph Two
+Paragraph Three
+<p>Paragraph One</p>+ +```jsx +
<p>Paragraph Two</p>
<p>Paragraph Three</p>
Paragraph One
+Paragraph Two
+Paragraph Three
+``` + ## Instructions diff --git a/curriculum/challenges/english/03-front-end-libraries/react/create-a-component-with-composition.english.md b/curriculum/challenges/english/03-front-end-libraries/react/create-a-component-with-composition.english.md index 6f5515eea0..7872b8fa40 100644 --- a/curriculum/challenges/english/03-front-end-libraries/react/create-a-component-with-composition.english.md +++ b/curriculum/challenges/english/03-front-end-libraries/react/create-a-component-with-composition.english.md @@ -9,7 +9,17 @@ isRequired: falseNavbar
, Dashboard
, and Footer
.
To compose these components together, you could create an App
parent component which renders each of these three components as children. To render a component as a child in a React component, you include the component name written as a custom HTML tag in the JSX. For example, in the render
method you could write:
-return (+ +```jsx +return ( +
<App>
<Navbar />
<Dashboard />
<Footer />
</App>
)
< />
like in this example), it renders the markup for that component in the location of the tag. This should illustrate the parent/child relationship between the App
component and the Navbar
, Dashboard
, and Footer
.
class
syntax. In the following example, Kitten
extends React.Component
:
-class Kitten extends React.Component {+ +```jsx +class Kitten extends React.Component { + constructor(props) { + super(props); + } + + render() { + return ( +
constructor(props) {
super(props);
}
render() {
return (
<h1>Hi</h1>
);
}
}
Kitten
which extends the React.Component
class. So the Kitten
class now has access to many useful React features, such as local state and lifecycle hooks. Don't worry if you aren't familiar with these terms yet, they will be covered in greater detail in later challenges.
Also notice the Kitten
class has a constructor
defined within it that calls super()
. It uses super()
to call the constructor of the parent class, in this case React.Component
. The constructor is a special method used during the initialization of objects that are created with the class
keyword. It is best practice to call a component's constructor
with super
, and pass props
to both. This makes sure the component is initialized properly. For now, know that it is standard for this code to be included. Soon you will see other uses for the constructor as well as props
.
state
. State consists of any data your application needs to know about, that can change over time. You want your apps to respond to state changes and present an updated UI when necessary. React offers a nice solution for the state management of modern web applications.
You create state in a React component by declaring a state
property on the component class in its constructor
. This initializes the component with state
when it is created. The state
property must be set to a JavaScript object
. Declaring it looks like this:
-this.state = {
// describe your state here
} + +```jsx +this.state = { + // describe your state here +} +``` + You have access to thestate
object throughout the life of your component. You can update it, render it in your UI, and pass it as props to child components. Thestate
object can be as complex or as simple as you need it to be. Note that you must create a class component by extendingReact.Component
in order to createstate
like this.
null
. One important thing to note is that React requires your function name to begin with a capital letter. Here's an example of a stateless functional component that assigns an HTML class in JSX:
-// After being transpiled, the <div> will have a CSS class of 'customClass'+ +```jsx +// After being transpiled, the
const DemoComponent = function() {
return (
<div className='customClass' />
);
};
props
or properties. This challenge looks at how arrays can be passed as props
. To pass an array to a JSX element, it must be treated as JavaScript and wrapped in curly braces.
-<ParentComponent>+ +```jsx +
<ChildComponent colors={["green", "blue", "red"]} />
</ParentComponent>
colors
. Array methods such as join()
can be used when accessing the property.
const ChildComponent = (props) => <p>{props.colors.join(', ')}</p>
This will join all colors
array items into a comma separated string and produce:
diff --git a/curriculum/challenges/english/03-front-end-libraries/react/pass-props-to-a-stateless-functional-component.english.md b/curriculum/challenges/english/03-front-end-libraries/react/pass-props-to-a-stateless-functional-component.english.md
index 2b4ec18341..520ae4f33f 100644
--- a/curriculum/challenges/english/03-front-end-libraries/react/pass-props-to-a-stateless-functional-component.english.md
+++ b/curriculum/challenges/english/03-front-end-libraries/react/pass-props-to-a-stateless-functional-component.english.md
@@ -8,9 +8,19 @@ isRequired: false
## Description
App
component which renders a child component called Welcome
which is a stateless functional component. You can pass Welcome
a user
property by writing:
-<App>+ +```jsx +
<Welcome user='Mark' />
</App>
user
is passed to the component Welcome
. Since Welcome
is a stateless functional component, it has access to this value like so:
-const Welcome = (props) => <h1>Hello, {props.user}!</h1>+ +```jsx +const Welcome = (props) =>
props
and when dealing with stateless functional components, you basically consider it as an argument to a function which returns JSX. You can access the value of the argument in the function body. With class components, you will see this is a little different.
state
and how to initialize state in the constructor
. There is also a way to change the component's state
. React provides a method for updating component state
called setState
. You call the setState
method within your component class like so: this.setState()
, passing in an object with key-value pairs. The keys are your state properties and the values are the updated state data. For instance, if we were storing a username
in state and wanted to update it, it would look like this:
-this.setState({+ +```jsx +this.setState({ + username: 'Lewis' +}); +``` + React expects you to never modify
username: 'Lewis'
});
state
directly, instead always use this.setState()
when state changes occur. Also, you should note that React may batch multiple state updates in order to improve performance. What this means is that state updates through the setState
method can be asynchronous. There is an alternative syntax for the setState
method which provides a way around this problem. This is rarely needed but it's good to keep it in mind! Please consult the React documentation for further details.
if/else
statements in JavaScript. They're not quite as robust as traditional if/else
statements, but they are very popular among React developers. One reason for this is because of how JSX is compiled, if/else
statements can't be inserted directly into JSX code. You might have noticed this a couple challenges ago — when an if/else
statement was required, it was always outside the return
statement. Ternary expressions can be an excellent alternative if you want to implement conditional logic within your JSX. Recall that a ternary operator has three parts, but you can combine several ternary expressions together. Here's the basic syntax:
-condition ? expressionIfTrue : expressionIfFalse+ +```js +condition ? expressionIfTrue : expressionIfFalse +``` +
createStore()
method.
In order to let us combine multiple reducers together, Redux provides the combineReducers()
method. This method accepts an object as an argument in which you define properties which associate keys to specific reducer functions. The name you give to the keys will be used by Redux as the name for the associated piece of state.
Typically, it is a good practice to create a reducer for each piece of application state when they are distinct or unique in some way. For example, in a note-taking app with user authentication, one reducer could handle authentication while another handles the text and notes that the user is submitting. For such an application, we might write the combineReducers()
method like this:
-const rootReducer = Redux.combineReducers({+ +```js +const rootReducer = Redux.combineReducers({ + auth: authenticationReducer, + notes: notesReducer +}); +``` + Now, the key
auth: authenticationReducer,
notes: notesReducer
});
notes
will contain all of the state associated with our notes and handled by our notesReducer
. This is how multiple reducers can be composed to manage more complex application state. In this example, the state held in the Redux store would then be a single object containing auth
and notes
properties.
dispatch
method is what you use to dispatch actions to the Redux store. Calling store.dispatch()
and passing the value returned from an action creator sends an action back to the store.
Recall that action creators return an object with a type property that specifies the action that has occurred. Then the method dispatches an action object to the Redux store. Based on the previous challenge's example, the following lines are equivalent, and both dispatch the action of type LOGIN
:
-store.dispatch(actionCreator());+ +```js +store.dispatch(actionCreator()); +store.dispatch({ type: 'LOGIN' }); +``` +
store.dispatch({ type: 'LOGIN' });
@while
directive is an option with similar functionality to the JavaScript while
loop. It creates CSS rules until a condition is met.
The @for
challenge gave an example to create a simple grid system. This can also work with @while
.
-$x: 1;+ +```scss +$x: 1; +@while $x < 13 { + .col-#{$x} { width: 100%/12 * $x;} + $x: $x + 1; +} +``` + First, define a variable
@while $x < 13 {
.col-#{$x} { width: 100%/12 * $x;}
$x: $x + 1;
}
$x
and set it to 1. Next, use the @while
directive to create the grid system while $x
is less than 13.
After setting the CSS rule for width
, $x
is incremented by 1 to avoid an infinite loop.
mixin
is a group of CSS declarations that can be reused throughout the style sheet.
Newer CSS features take time before they are fully adopted and ready to use in all browsers. As features are added to browsers, CSS rules using them may need vendor prefixes. Consider "box-shadow":
-div {+ +```scss +div { + -webkit-box-shadow: 0px 0px 4px #fff; + -moz-box-shadow: 0px 0px 4px #fff; + -ms-box-shadow: 0px 0px 4px #fff; + box-shadow: 0px 0px 4px #fff; +} +``` + It's a lot of typing to re-write this rule for all the elements that have a
-webkit-box-shadow: 0px 0px 4px #fff;
-moz-box-shadow: 0px 0px 4px #fff;
-ms-box-shadow: 0px 0px 4px #fff;
box-shadow: 0px 0px 4px #fff;
}
box-shadow
, or to change each value to test different effects.
Mixins
are like functions for CSS. Here is how to write one:
-@mixin box-shadow($x, $y, $blur, $c){+ +```scss +@mixin box-shadow($x, $y, $blur, $c){ + -webkit-box-shadow: $x, $y, $blur, $c; + -moz-box-shadow: $x, $y, $blur, $c; + -ms-box-shadow: $x, $y, $blur, $c; + box-shadow: $x, $y, $blur, $c; +} +``` + The definition starts with
-webkit-box-shadow: $x, $y, $blur, $c;
-moz-box-shadow: $x, $y, $blur, $c;
-ms-box-shadow: $x, $y, $blur, $c;
box-shadow: $x, $y, $blur, $c;
}
@mixin
followed by a custom name. The parameters (the $x
, $y
, $blur
, and $c
in the example above) are optional.
Now any time a box-shadow
rule is needed, only a single line calling the mixin
replaces having to type all the vendor prefixes. A mixin
is called with the @include
directive:
-div {+ +```scss +div { + @include box-shadow(0px, 0px, 4px, #fff); +} +``` +
@include box-shadow(0px, 0px, 4px, #fff);
}
extend
that makes it easy to borrow the CSS rules from one element and build upon them in another.
For example, the below block of CSS rules style a .panel
class. It has a background-color
, height
and border
.
-.panel{+ +```scss +.panel{ + background-color: red; + height: 70px; + border: 2px solid green; +} +``` + Now you want another panel called
background-color: red;
height: 70px;
border: 2px solid green;
}
.big-panel
. It has the same base properties as .panel
, but also needs a width
and font-size
.
It's possible to copy and paste the initial CSS rules from .panel
, but the code becomes repetitive as you add more types of panels.
The extend
directive is a simple way to reuse the rules written for one element, then add more for another:
-.big-panel{+ +```scss +.big-panel{ + @extend .panel; + width: 150px; + font-size: 2em; +} +``` + The
@extend .panel;
width: 150px;
font-size: 2em;
}
.big-panel
will have the same properties as .panel
in addition to the new styles.
nesting
of CSS rules, which is a useful way of organizing a style sheet.
Normally, each element is targeted on a different line to style it, like so:
-nav {+ +```scss +nav { + background-color: red; +} + +nav ul { + list-style: none; +} + +nav ul li { + display: inline-block; +} +``` + For a large project, the CSS file will have many lines and rules. This is where
background-color: red;
}
nav ul {
list-style: none;
}
nav ul li {
display: inline-block;
}
nesting
can help organize your code by placing child style rules within the respective parent elements:
-nav {+ +```scss +nav { + background-color: red; + + ul { + list-style: none; + + li { + display: inline-block; + } + } +} + +``` +
background-color: red;
ul {
list-style: none;
li {
display: inline-block;
}
}
}
Partials
in Sass are separate files that hold segments of CSS code. These are imported and used in other Sass files. This is a great way to group similar code into a module to keep it organized.
Names for partials
start with the underscore (_
) character, which tells Sass it is a small segment of CSS and not to convert it into a CSS file. Also, Sass files end with the .scss
file extension. To bring the code in the partial
into another Sass file, use the @import
directive.
For example, if all your mixins
are saved in a partial
named "_mixins.scss", and they are needed in the "main.scss" file, this is how to use them in the main file:
-// In the main.scss file+ +```scss +// In the main.scss file + +@import 'mixins' +``` + Note that the underscore and file extension are not needed in the
@import 'mixins'
import
statement - Sass understands it is a partial
. Once a partial
is imported into a file, all variables, mixins
, and other code are available to use.
diff --git a/curriculum/challenges/english/03-front-end-libraries/sass/store-data-with-sass-variables.english.md b/curriculum/challenges/english/03-front-end-libraries/sass/store-data-with-sass-variables.english.md
index 7932fe118a..86fed2586a 100644
--- a/curriculum/challenges/english/03-front-end-libraries/sass/store-data-with-sass-variables.english.md
+++ b/curriculum/challenges/english/03-front-end-libraries/sass/store-data-with-sass-variables.english.md
@@ -9,7 +9,18 @@ challengeType: 0
One feature of Sass that's different than CSS is it uses variables. They are declared and set to store data, similar to JavaScript.
In JavaScript, variables are defined using the let
and const
keywords. In Sass, variables start with a $
followed by the variable name.
Here are a couple examples:
-$main-fonts: Arial, sans-serif;+ +```scss +$main-fonts: Arial, sans-serif; +$headings-color: green; + +//To use variables: +h1 { + font-family: $main-fonts; + color: $headings-color; +} +``` + One example where variables are useful is when a number of elements need to be the same color. If that color is changed, the only place to edit the code is the variable value. diff --git a/curriculum/challenges/english/03-front-end-libraries/sass/use-each-to-map-over-items-in-a-list.english.md b/curriculum/challenges/english/03-front-end-libraries/sass/use-each-to-map-over-items-in-a-list.english.md index c0e3c08a77..732d2ffde1 100644 --- a/curriculum/challenges/english/03-front-end-libraries/sass/use-each-to-map-over-items-in-a-list.english.md +++ b/curriculum/challenges/english/03-front-end-libraries/sass/use-each-to-map-over-items-in-a-list.english.md @@ -8,12 +8,40 @@ challengeType: 0
$headings-color: green;
//To use variables:
h1 {
font-family: $main-fonts;
color: $headings-color;
}
@for
directive uses a starting and ending value to loop a certain number of times. Sass also offers the @each
directive which loops over each item in a list or map.
On each iteration, the variable gets assigned to the current value from the list or map.
-@each $color in blue, red, green {+ +```scss +@each $color in blue, red, green { + .#{$color}-text {color: $color;} +} +``` + A map has slightly different syntax. Here's an example: -
.#{$color}-text {color: $color;}
}
$colors: (color1: blue, color2: red, color3: green);+ +```scss +$colors: (color1: blue, color2: red, color3: green); + +@each $key, $color in $colors { + .#{$color}-text {color: $color;} +} +``` + Note that the
@each $key, $color in $colors {
.#{$color}-text {color: $color;}
}
$key
variable is needed to reference the keys in the map. Otherwise, the compiled CSS would have color1
, color2
... in it.
Both of the above code examples are converted into the following CSS:
-.blue-text {+ +```scss +.blue-text { + color: blue; +} + +.red-text { + color: red; +} + +.green-text { + color: green; +} +``` +
color: blue;
}
.red-text {
color: red;
}
.green-text {
color: green;
}
@for
directive adds styles in a loop, very similar to a for
loop in JavaScript.
@for
is used in two ways: "start through end" or "start to end". The main difference is that the "start to end" excludes the end number as part of the count, and "start through end" includes the end number as part of the count.
Here's a start through end example:
-@for $i from 1 through 12 {+ +```scss +@for $i from 1 through 12 { + .col-#{$i} { width: 100%/12 * $i; } +} +``` + The
.col-#{$i} { width: 100%/12 * $i; }
}
#{$i}
part is the syntax to combine a variable (i
) with text to make a string. When the Sass file is converted to CSS, it looks like this:
-.col-1 {+ +```scss +.col-1 { + width: 8.33333%; +} + +.col-2 { + width: 16.66667%; +} + +... + +.col-12 { + width: 100%; +} +``` + This is a powerful way to create a grid layout. Now you have twelve options for column widths available as CSS classes. diff --git a/curriculum/challenges/english/03-front-end-libraries/sass/use-if-and-else-to-add-logic-to-your-styles.english.md b/curriculum/challenges/english/03-front-end-libraries/sass/use-if-and-else-to-add-logic-to-your-styles.english.md index 211ee11954..b8f15d015f 100644 --- a/curriculum/challenges/english/03-front-end-libraries/sass/use-if-and-else-to-add-logic-to-your-styles.english.md +++ b/curriculum/challenges/english/03-front-end-libraries/sass/use-if-and-else-to-add-logic-to-your-styles.english.md @@ -7,15 +7,46 @@ challengeType: 0 ## Description
width: 8.33333%;
}
.col-2 {
width: 16.66667%;
}
...
.col-12 {
width: 100%;
}
@if
directive in Sass is useful to test for a specific case - it works just like the if
statement in JavaScript.
-@mixin make-bold($bool) {+ +```scss +@mixin make-bold($bool) { + @if $bool == true { + font-weight: bold; + } +} +``` + And just like in JavaScript,
@if $bool == true {
font-weight: bold;
}
}
@else if
and @else
test for more conditions:
-@mixin text-effect($val) {+ +```scss +@mixin text-effect($val) { + @if $val == danger { + color: red; + } + @else if $val == alert { + color: yellow; + } + @else if $val == success { + color: green; + } + @else { + color: black; + } +} +``` +
@if $val == danger {
color: red;
}
@else if $val == alert {
color: yellow;
}
@else if $val == success {
color: green;
}
@else {
color: black;
}
}
mixin
called border-stroke
that takes a parameter $val
. The mixin
should check for the following conditions using @if
, @else if
, and @else
:
-light - 1px solid black+ +```scss +light - 1px solid black +medium - 3px solid black +heavy - 6px solid black +``` + If
medium - 3px solid black
heavy - 6px solid black
$val
is not light
, medium
, or heavy
, the border should be set to none
.