React router #343
No reviewers
Labels
No labels
area: devops
area: discovery
area: docs
area: livestream
area: proposal
consider soon
dependencies
Epic
good first issue
hacktoberfest
help wanted
icebox
level: 1
level: 2
level: 3
level: 4
needs: exploration
needs: grooming
needs: priority
needs: repro
needs: tech design
on hold
Osprey
priority: blocker
priority: high
priority: low
priority: medium
protocol dependent
resilience
Tom's Wishlist
type: bug
type: discussion
type: error handling
type: improvement
type: new feature
type: refactor
type: task
type: testing
unplanned
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: LBRYCommunity/spee.ch#343
Loading…
Reference in a new issue
No description provided.
Delete branch "react-router"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Initial comments. I'll do another look through later. Looking great though!
I think generally the pattern is that an action is
{ type: "some string", data: { name, id... } }
just to keep things consistent.data
can be an object or a string, but I think it's helpful to put everything inside of thatWhy do you do
const that = this
?I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same
<AssetDisplay />
it will make these requests again, even if you just made them a second agoThis should be a
button
if it isn't linking anywhere.Any reason these aren't just css?
You can use destructuring twice to avoid all the repeated
this.props.claimData
const { claimData: { name, claimId... } } = this.props
Then you can just use
name={name}
Will these nested values always exist?
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch
updateClaimsData
action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)Instead of having a
activeClassName
prop, it might be simpler to use anactive
prop. Then you can just change the active class name once inside theNavLink
component@ -121,3 +114,3 @@
.then(() => {
return that.validatePublishParams();
return this.validatePublishParams();
})
Not really a comment on this PR but it might be worth looking into
fetch
instead of dealing withxhr
In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a
Redirect
component or just a route with nopath
prop.@ -4,3 +2,4 @@
<div id="react-app" class="row row--tall flex-container--column">
<div class="row row--padded row--tall flex-container--column flex-container--center-center">
<p>loading...</p>
{{> progressBar}}
Not sure if you meant to keep this in? I think this will always be rendered.
I had a misunderstanding of how the
this
context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.oops
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when
show
is undefined. Which would cause an errror.cannot read property 'showChannel
of undefined`.Or if any of those children would be undefined which would throw an error
@ -4,3 +2,4 @@
<div id="react-app" class="row row--tall flex-container--column">
<div class="row row--padded row--tall flex-container--column flex-container--center-center">
<p>loading...</p>
{{> progressBar}}
I meant to keep the loading bar in so it will render until the app is rendered. Once the app renders it replaces the content of the div and removes the loading bar.
@ -121,3 +114,3 @@
.then(() => {
return that.validatePublishParams();
return this.validatePublishParams();
})
Cool. Yeah, I replaced most xhr requests with fetch in the app. I kept this one for the publish request because I wanted to set event listeners on the request and wasn't sure if I could do that with fetch. I'll look into that.
I'm not quite sure I understand. Do you mean create my own
NavLink
component ( rather than using theNavLink
fromreact-router-dom
) and control the className from inside the component?Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
Oh I didn't realize that was a
react-router-dom
component. But yeah, I would make a customNavLink
component that uses thereact-router-dom
component. Then you can extend the functionality/style very easily.similar to this https://github.com/lbryio/lbry-app/blob/redesign-wip/src/renderer/component/link/view.jsx
Looks good. Just some concerns with how you are bringing in some of the already fetched data. I think that can be taken out of the component.
@ -1,51 +1,30 @@
const logger = require('winston');
module.exports = {
handleErrorResponse: function (originalUrl, ip, error, res) {
Why changing to 200?
I don't have any experience using
redux-saga
so I might just not understand what is happening.Generally you want
XX_SUCCESS
andXX_FAIL
actions separated. That makes it a lot easier handling the data on the reducer.If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
@ -1,51 +1,30 @@
const logger = require('winston');
module.exports = {
handleErrorResponse: function (originalUrl, ip, error, res) {
I am trying to create a pattern where the server responds with a 200 as long as it processed the request correctly, and then responds with a
success
and amessage
ordata
field. I.e.{"success": "false", "message": "connection refused. The daemon may not be running"}
. This way, if the client wanted some data but the daemon was off, it would get a200
response that the request was completed, and then the client could check the response to see if it was successful or not and whether the data is present. My goal was to help myself (and api users) to distinguish between an error where something was unavailable but the request was handled properly (resulting in a200
) vs a request that I thought would be handled but wasn't, resulting in some other error. Thoughts?@ -1,51 +1,30 @@
const logger = require('winston');
module.exports = {
handleErrorResponse: function (originalUrl, ip, error, res) {
I think proper error codes would still be preferable. Even if the request is handled properly, there is still an error. If I see a 200 response, I assume my request was successful. The
fetch
api handles errors really nicely too, so I think if anything you are creating more work.In my opinion it doesn't really matter if a request was handled successfully. If the data doesn't make it, it still fails. You can still add info with the error message and code.
I think you are nearly there with the
mapStateToProps
improvements. Just need to pull the last bit of un-needed logic out of the component.This probably shouldn't be called
XXX_ASYNC
since it isn't asyncI think you are still creating more work than necessary with this. In my opinion
previousRequest
shouldn't even exist. In themapStateToProps
you should be able to map theasset
from your state into the component. If!asset
then make the request.I also think
onShowNewAsset
andonNewRequest
can be combined. More specifically I don't thinkonShowNewAsset
is needed. It might just be my lack of understanding with the current data flow, but you shouldn't need to manually say "show this asset". A better approach would be "select the asset with this id".Same comments above about
previousRequest
. I think a more understandable approach would just be:@ -1,51 +1,30 @@
const logger = require('winston');
module.exports = {
handleErrorResponse: function (originalUrl, ip, error, res) {
That makes a lot of sense, and I was running into a lot of the latter situation where I had to check
success
in addition to checking for errors. I updated it and that cleaned up the response handling a lot.Ok, I think I'm getting closer. I was able to do away with
onShowNewAsset
and combine the needed logic from its action (retrieving the asset's claim data) intoonNewRequest
. That allowed me to removepreviousRequest
from the props I am passing to the<ShowAsset />
component. However, I am still checking for apreviousRequest
in the mapStateToProps function. Do you see a way to avoid that step altogether? The reason for storing and checking the previous requests is to avoid having to retrieve new information for a request that was already made (i.e. to avoid having to request the fullclaimId
from the server). I'm trying to figure out if that can be skipped or consolidated, but I am not sure how.See above re: previous request. I mostly fixed this, but not sure if more consolidation can be done.
@seanyesmunt I was able to pull the request validation out of
<ShowAsset />
and remove that component entirely so that<ShowPage />
triggers theonNewChannelRequest
oronNewAssetRequest
actions. Those actions then retrieve the data and create therequest
along with theasset
orchannel
. I also consolidated thechannelRequests
andassetRequests
into onerequestList
. What do you think?@billbitt Looks great. The components are definitely a lot simpler. I'm just now thinking that most of the logic inside
react/containers/ShowPage/view.jsx
can be moved into redux still. You can fetch the actual asset directly after fetching the longForm if you haven't seen that longForm before. No need to wait for theShowPage
to render to make the actual asset request.Not a super big deal, but I think that should be done at some point. I started on some pseudo code and got a little carried away lol. But I think it could look something like this
@seanyesmunt I moved all that logic out of
<ShowPage />
and into ahandleShowPageUri
action. That action parses it, validates it, and then triggers aonNewChannelRequest
oronNewAssetRequest
action. In those actions, I added checks to thestore
to get the lists like in your pseudocode. Can you check it out?@ -0,0 +9,4 @@
// claim will be an asset claim
// the identifier could be a channel or a claim id
let isChannel, channelName, channelClaimId, claimId, claimName, extension;
try {
I think you need to add a state check here too. To see if that request exists. It looks like it will add the request to the list every time.