Prepending Dynamic Retweets:

update in time:

  • first we have to let the retweet be updated after click “retweet”
  • in /twittme-web/src/tweets/components.js

    • add “didRetweet”
    • setTweetsInit() and setTweets() ```javascript export function Tweet(props) { //const { tweet } = props; const { tweet, didRetweet } = props; //new element

    const [actionTweet, setActionTweet] = useState( props.tweet ? props.tweet : null );

    //…

    const handlePerformAction = (newActionTweet, status) => { if (status === 200) {

    1. setActionTweet(newActionTweet);

    } else if (status === 201) {

    1. //new
    2. if (didRetweet) {
    3. didRetweet(newActionTweet);
    4. }

    } };

    //… }

export function TweetsList(props) { const [tweetsInit, setTweetsInit] = useState([]); const [tweets, setTweets] = useState([]);

const [tweetsDidSet, setTweetsDidSet] = useState(false);

//…

//new const handleDidRetweet = (newTweet) => { const updateTweetsInit = […tweetsInit]; //grabbing tweetsInit list updateTweetsInit.unshift(newTweet); //add newTweet to the beginning of updateTweetsInit setTweetsInit(updateTweetsInit); //update status const updateFinalTweets = […tweets]; //grabbing tweets list updateFinalTweets.unshift(tweets); //add tweets to the beginning of updateFinalTweets setTweets(updateFinalTweets); //update status };

return tweets.map((item, index) => { return ( ); }); }

  1. to test, runserver and npm start, access localhost:30<br />click this retweet button: <br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1243266/1594873011213-01101d41-c992-4022-9cc7-a2fae930aa69.png#align=left&display=inline&height=452&margin=%5Bobject%20Object%5D&name=image.png&originHeight=904&originWidth=1811&size=74558&status=done&style=none&width=905.5)<br />a pair of tweet and retweet will be immediately updated without refreshing<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1243266/1594873053511-3f1abdf9-aaee-414e-9a93-0590355fe564.png#align=left&display=inline&height=438&margin=%5Bobject%20Object%5D&name=image.png&originHeight=875&originWidth=1812&size=78826&status=done&style=none&width=906)<br />but another challenge is that if we click retweet button of a retweet(such as retweet button in 106), the status will not be updated immediately.
  2. <a name="4FIPH"></a>
  3. #### hide actions for parent tweets:
  4. - we need to hide actions on parent tweets to avoid problems
  5. - still in /twittme-web/src/tweets/components.js
  6. - add "hideActions"
  7. ```javascript
  8. export function ParentTweet(props) {
  9. const { tweet } = props;
  10. return tweet.parent ? (
  11. <div className="row">
  12. <div className="col-11 mx-auto p-3 border rounded">
  13. <p className="mb-0 text-muted small">Retweet</p>
  14. <Tweet hideActions className={" "} tweet={tweet.parent} />
  15. </div>
  16. </div>
  17. ) : null;
  18. /*
  19. return tweet.parent ? (
  20. <div className="row">
  21. <div className="col-11 mx-auto p-3 border rounded">
  22. <p className="mb-0 text-muted small">Retweet</p>
  23. <Tweet className={" "} tweet={tweet.parent} />
  24. </div>
  25. </div>
  26. ) : null;
  27. */
  28. }
  29. export function Tweet(props) {
  30. //const { tweet, didRetweet } = props;
  31. const { tweet, didRetweet, hideActions } = props; //new element
  32. const [actionTweet, setActionTweet] = useState(
  33. props.tweet ? props.tweet : null
  34. );
  35. const className = props.className
  36. ? props.className
  37. : "col-10 mx-auto col-md-6";
  38. const handlePerformAction = (newActionTweet, status) => {
  39. if (status === 200) {
  40. setActionTweet(newActionTweet);
  41. } else if (status === 201) {
  42. if (didRetweet) {
  43. didRetweet(newActionTweet);
  44. }
  45. }
  46. };
  47. return (
  48. <div className={className}>
  49. <div>
  50. <p>
  51. {tweet.id} - {tweet.content}
  52. </p>
  53. <ParentTweet tweet={tweet} />
  54. </div>
  55. {(actionTweet && hideActions !== true) && (
  56. <div className="btn btn-group">
  57. <ActionBtn
  58. tweet={actionTweet}
  59. didPerformAction={handlePerformAction}
  60. action={{ type: "like", display: "Likes" }}
  61. />
  62. <ActionBtn
  63. tweet={actionTweet}
  64. didPerformAction={handlePerformAction}
  65. action={{ type: "unlike", display: "Unlike" }}
  66. />
  67. <ActionBtn
  68. tweet={actionTweet}
  69. didPerformAction={handlePerformAction}
  70. action={{ type: "retweet", display: "Retweet" }}
  71. />
  72. </div>
  73. )}
  74. </div>
  75. );
  76. /*
  77. return (
  78. <div className={className}>
  79. <div>
  80. <p>
  81. {tweet.id} - {tweet.content}
  82. </p>
  83. <ParentTweet tweet={tweet} />
  84. </div>
  85. {actionTweet && (
  86. <div className="btn btn-group">
  87. <ActionBtn
  88. tweet={actionTweet}
  89. didPerformAction={handlePerformAction}
  90. action={{ type: "like", display: "Likes" }}
  91. />
  92. <ActionBtn
  93. tweet={actionTweet}
  94. didPerformAction={handlePerformAction}
  95. action={{ type: "unlike", display: "Unlike" }}
  96. />
  97. <ActionBtn
  98. tweet={actionTweet}
  99. didPerformAction={handlePerformAction}
  100. action={{ type: "retweet", display: "Retweet" }}
  101. />
  102. </div>
  103. )}
  104. </div>
  105. );
  106. */
  107. }

refresh and see the page:
image.png
now only new tweets have action buttons, and it make the page more organized with too complicated relationships.

Set Data Props on ReactDOM Render:

about dataset:

  • do a test first

    • add an element “data-username” in “tweetme-2” in /twittme-web/public/index.html ```html

    1. - console.log(tweetsEl.dataset) to see what's new in /twittme-web/src/index.js
    2. ```javascript
    3. const tweetsEl = document.getElementById("tweetme-2")
    4. if (tweetsEl) {
    5. console.log(tweetsEl.dataset) //new
    6. ReactDOM.render(<TweetsComponent />, tweetsEl);
    7. }

    refresh and see the console log:
    image.png
    we have a username: “root” as we setup.

  • to test again, add new element in /twittme-web/public/index.html

    1. <body>
    2. <noscript>You need to enable JavaScript to run this app.</noscript>
    3. <!--
    4. <div id="tweetme-2" data-username="root"></div>
    5. -->
    6. <div id="tweetme-2" data-username="root" data-valid="true"></div>
    7. <!--
    8. This HTML file is a template.
    9. If you open it directly in the browser, you will see an empty page.
    10. You can add webfonts, meta tags, or analytics to this file.
    11. The build step will place the bundled scripts into the <body> tag.
    12. To begin the development, run `npm start` or `yarn start`.
    13. To create a production bundle, use `npm run build` or `yarn build`.
    14. -->
    15. </body>

    refresh and see the console log:
    image.png
    “valid” is shown either.

so we just need “data-“ in the name of elements in a div to let it be included in the dataset.

pass data as component:

The next step, we have to pass dataset to

  • For example, the previous step we have “username”

    • we add some details in /twittme-web/src/index.js

      1. const tweetsEl = document.getElementById("tweetme-2")
      2. if (tweetsEl) {
      3. console.log(tweetsEl.dataset)
      4. //ReactDOM.render(<TweetsComponent />, tweetsEl);
      5. ReactDOM.render(<TweetsComponent username={tweetsEl.dataset.username} />, tweetsEl);
      6. //new
      7. }
    • to see what is sent, in /twittme-web/src/tweets/components.js ```javascript export function TweetsComponent(props) { console.log(props); //new

    //… } ``` refresh and access localhost:30
    image.png
    and “username” is successfully sent as a tweet component.

pass dataset as component:

The previous method successfully passed something, but it’s too complicated if we need to insert all names.
We can pass all at once:

  • in /twittme-web/src/index.js
    1. const e = React.createElement //new
    2. const tweetsEl = document.getElementById("tweetme-2")
    3. if (tweetsEl) {
    4. //console.log(tweetsEl.dataset)
    5. const MyComponent = e(TweetsComponent, tweetsEl.dataset) //new
    6. //ReactDOM.render(<TweetsComponent username={tweetsEl.dataset.username} />, tweetsEl);
    7. ReactDOM.render(MyComponent, tweetsEl);
    8. }
    refresh and access homepage:
    image.png
    both username and valid are passed.

Now we can update list view by passed elements.